PHP抽象类与接口的区别实例详解


Posted in PHP onMay 09, 2019

本文实例讲述了PHP抽象类与接口的区别。分享给大家供大家参考,具体如下:

抽象类abstract

概念

定义为抽象的类不能被实例化。任何一个类,如果有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的类。

继承一个抽象类的时候,子类必须定义父类中的所有抽象方法,这些方法的访问控制必须喝父类中一样或者更为宽松。

例如,某个抽象方法被声明为proteced,那么子类中的实现,就应该声明为protected或者public,而不能定义为private。

方法的调用方式必须匹配,即类型和所需参数数量必须一致,例如,子类定义了一个可选参数,而父类抽象方法中没有声明,则两者的声明并没有冲突。

特点

  • 抽象类继承,使用关键字extends。
  • 抽象类可以声明各种变量、常量、方法。
  • 抽象类可以有构造函数。
  • 抽象类中的方法可以是公开的public、保护的protected、私有的private。
  • 一个类只能继承一个抽象类。

示例

示例一

<?php
// 抽象类
abstract class AbstractClasss
{
  // 强制要求子类定义这些方法
  abstract protected function getValue();
  abstract protected function prefixValue();
  // 普通方法(非抽象方法)
  public function printOut() 
  {
    print $this->getValue() . "\n";
  }
}
// 子类
class ConcreteClassOne extends AbstractClass
{
  protected function getValue()
  {
    return "ConcreteClassOne";
  }
  public function prefixValues($prefix)
  {
    return "{$prefix}ConcreteClassOne";
  }
}
// 子类
class ConcreteClassTwo extends AbstractClass
{
  protected function getValue()
  {
    return "ConcreteClassTwo";
  }
  public function prefixValue($prefix)
  {
    return "{$prefix}ConcreteClassTwo";
  }
}
// 实例化第一个子类
$classOne = new ConcreteClassOne;
$classOne->printOut();
echo $classOne->prefixValue('FOO_') . "\n";
// 实例化第二个子类
$classTwo = new ConcreteClassTwo;
$classTwo->printOut();
echo $classTwo->prefixValue('FOO_') . "\n";

结果输出

ConcreteClassOne
FOO_ConcreteClassOne

ConcreteClassTwo
FOO_ConcreteClassTwo

示例二

<?php
// 抽象类
abstract class AbstractClass
{
  // 我们的抽象方法仅需要定义需要的参数
  abstract protected function prefixName($name);
}
// 子类
class ConcreteClass extends AbstractClass
{
  // 我们的子类可以定义父类签名中不存在的可选参数
  public function prefixName($name, $separator = ".")
  {
    if ($name == "Pacman") {
      $prefix = "Mr";
    } elseif ($name == "Pacwoman") {
      $prefix = "Mrs";
    } else {
      $prefix = "";
    }
    return "{$prefix}{$separator} {$name}";
  }
}
// 实例化子类
$class = new ConcreteClass;
echo $class->prefixName("Pacman") . "\n";
echo $class->prefixName("Pacwoman") . "\n";

结果输出

Mr. Pacman
Mrs, Pacwoman

接口interface

概念

使用接口interface,可以指定某个类必须实现那些方法,但是不需要定义这些方法的具体内容。

要实现一个接口,使用implements操作符,类中必须实现接口中定义的所有方法。

特点

  • 接口的实现,使用关键字implements。
  • 接口中不能声明变量,但是可以声明常量。
  • 接口中没有构造函数。
  • 接口中的方法默认都是公开的public。
  • 一个类可以实现多个接口。

示例

示例一 、 实现接口

<?php
// 声明一个iTemplate接口
interface iTemplate
{
  public function setVariable($name, $var);
  public function getHtml($template);
}
// 实现接口
// 下面的写法是正确的
class Template implements iTemplate
{
  private $vars = array();
  public function setVariable($name, $var)
  {
    $this->vars[$name] = $var;
  }
  public function getHtml($template)
  {
    foreach($this->vars as $name => $value) {
      $template = str_replace('{' . $name . '}', $value, $template);
    }
    return $template;
  }
}
// 下面的写法是错误的,会报错,因为没有实现 getHtml()
// Fatal error: Class BadTemplate contains 1 abstract methonds
// and must therefore be declared abstaract (iTemplate::getHtml)
class BadTemplate implements iTemplate
{
  private $vars = array();
  public function setVariable($name, $var)
  {
    $this->vars[$name] = $var;
  }
}

示例二 、 可扩充接口

<?php
interface a
{
  public function foo();
}
interface b extends a
{
  public function baz(Baz $baz);
}
// 正确的写法
class c implements b
{
  public function foo()
  {
  }
  public function baz(Baz $baz)
  {
  }
}
// 错误的写法会导致一个致命的错误
class d implements b
{
  public function foo()
  {
  }
  public function baz(Foo $foo)
  {
  }
}

示例三 、 继承多个接口

<?php
interface a
{
  pubLic function foo();
}
interface b
{
  public function bar();
}
interface c extends a, b
{
  public function baz();
}
class d implements c
{
  public function foo()
  {
  }
  public function bar()
  {
  }
  public function baz()
  {
  }
}

示例四 、使用接口常量

<?php
interface a
{
  const b = 'Interface constant';
}
// 输出接口变量
echo a:b;
// 错误的写法,因为常量不能被覆盖。
// 接口常量的概念和类常量的是一样的。
class b implements a
{
  const b = 'Class constant'
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
MySQL授权问题总结
May 06 PHP
mysql时区问题
Mar 26 PHP
php模拟socket一次连接,多次发送数据的实现代码
Jul 26 PHP
如何获知PHP程序占用多少内存(memory_get_usage)
Sep 23 PHP
PHP编码转换
Nov 05 PHP
php通过数组实现多条件查询实现方法(字符串分割)
May 06 PHP
PHP把MSSQL数据导入到MYSQL的方法
Dec 27 PHP
php短址转换实现方法
Feb 25 PHP
CodeIgniter配置之autoload.php自动加载用法分析
Jan 20 PHP
PHP怎样用正则抓取页面中的网址
Aug 09 PHP
php实现评论回复删除功能
May 23 PHP
php使用curl模拟多线程实现批处理功能示例
Jul 25 PHP
php和vue配合使用技巧和方法
May 09 #PHP
php查询内存信息操作示例
May 09 #PHP
PHP利用百度ai实现文本和图片审核
May 08 #PHP
PHP回调函数简单用法示例
May 08 #PHP
Thinkphp5+plupload实现的图片上传功能示例【支持实时预览】
May 08 #PHP
PHP封装类似thinkphp连贯操作数据库Db类与简单应用示例
May 08 #PHP
php封装的pdo数据库操作工具类与用法示例
May 08 #PHP
You might like
支持php4、php5的mysql数据库操作类
2008/01/10 PHP
PHP操作数组的一些函数整理介绍
2011/07/17 PHP
从零开始学YII2框架(一)通过Composer安装Yii2框架
2014/08/20 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
解决extjs在firefox中关闭窗口再打开后iframe中js函数访问不到的问题
2008/11/06 Javascript
js中escape对应的C#解码函数 UrlDecode
2012/12/16 Javascript
解决jquery submit()提交表单提示:f[s] is not a function
2013/01/23 Javascript
jquery js 重置表单 reset()具体实现代码
2013/08/05 Javascript
jQuery简单实现日历的方法
2015/05/04 Javascript
JavaScript实现给按钮加上双重动作的方法
2015/08/14 Javascript
js+flash实现的5图变换效果广告代码(附演示与demo源码下载)
2016/04/01 Javascript
jQuery 获取select选中值及清除选中状态
2016/12/13 Javascript
JavaScript实现弹窗效果代码分析
2017/03/09 Javascript
jquery引入外部CDN 加载失败则引入本地jq库
2018/05/23 jQuery
vue-cli脚手架的安装教程图解
2018/09/02 Javascript
vue实现配置全局访问路径头(axios)
2019/11/01 Javascript
vue组件添加事件@click.native操作
2020/10/30 Javascript
vue 使用微信jssdk,调用微信相册上传图片功能
2020/11/13 Javascript
Node.js文本文件BOM头的去除方法
2020/11/22 Javascript
[00:12]DAC SOLO赛卫冕冠军 VG.Paparazi灬展现SOLO技巧
2018/04/06 DOTA
python pdb调试方法分享
2014/01/21 Python
Python实现TCP/IP协议下的端口转发及重定向示例
2016/06/14 Python
python实现校园网自动登录的示例讲解
2018/04/22 Python
Selenium定位元素操作示例
2018/08/10 Python
解决Python3.5+OpenCV3.2读取图像的问题
2018/12/05 Python
对pandas的算术运算和数据对齐实例详解
2018/12/22 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
Python解析命令行读取参数之argparse模块
2019/07/26 Python
python数据处理——对pandas进行数据变频或插值实例
2020/04/22 Python
解决Keras中循环使用K.ctc_decode内存不释放的问题
2020/06/29 Python
一款CSS3实现多功能下拉菜单(带分享按)的教程
2014/11/05 HTML / CSS
OSPF有什么优点?为什么OSPF比RIP收敛快?
2013/02/13 面试题
介绍一下XMLHttpRequest对象
2012/02/12 面试题
中秋节主题班会
2015/08/14 职场文书
Vue实现动态查询规则生成组件
2021/05/27 Vue.js
Win11 21h2可以升级22h2吗?看看你的电脑符不符合要求
2022/07/07 数码科技