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 相关文章推荐
用PHP实现多级树型菜单
Oct 09 PHP
PHP Session_Regenerate_ID函数双释放内存破坏漏洞
Jan 27 PHP
php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
Sep 28 PHP
使用PHP强制下载PDF文件示例
Jan 17 PHP
php中try catch捕获异常实例详解
Nov 21 PHP
PHP使用glob函数遍历目录或文件夹的方法
Dec 16 PHP
PHP制作用户注册系统
Oct 23 PHP
Yii2中SqlDataProvider用法示例
Sep 22 PHP
PHP实现的数独求解问题示例
Apr 18 PHP
yii2.0整合阿里云oss的示例代码
Sep 19 PHP
Laravel关系模型指定条件查询方法
Oct 10 PHP
php实现微信小程序授权登录功能(实现流程)
Nov 13 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
一个阿拉伯数字转中文数字的函数
2006/10/09 PHP
编写自己的php扩展函数
2006/10/09 PHP
将PHP作为Shell脚本语言使用
2006/10/09 PHP
PHP4实际应用经验篇(9)
2006/10/09 PHP
ThinkPHP中I(),U(),$this-&gt;post()等函数用法
2014/11/22 PHP
php获取'/'传参的值简单方法
2017/07/13 PHP
PhpStorm 2020.3:新增开箱即用的PHP 8属性(推荐)
2020/10/30 PHP
基于jQuery实现的百度导航li拖放排列效果,即时更新数据库
2012/07/31 Javascript
JavaScript 盒模型 尺寸深入理解
2012/12/31 Javascript
浅谈JavaScript function函数种类
2014/12/29 Javascript
JavaScript中document.forms[0]与getElementByName区别
2015/01/21 Javascript
javaScript中push函数用法实例分析
2015/06/08 Javascript
正则表达式(语法篇推荐)
2016/06/24 Javascript
jQuery阻止移动端遮罩层后页面滚动
2017/03/15 Javascript
react.js CMS 删除功能的实现方法
2017/04/17 Javascript
AngularJS实现图片上传和预览功能的方法分析
2017/11/08 Javascript
javascript+HTML5 canvas绘制时钟功能示例
2019/05/15 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
2020/09/08 Javascript
Python3.5集合及其常见运算实例详解
2019/05/01 Python
布隆过滤器的概述及Python实现方法
2019/12/08 Python
opencv3/C++ 平面对象识别&amp;透视变换方式
2019/12/11 Python
python程序输出无内容的解决方式
2020/04/09 Python
深入浅析css3 border-image边框图像详解
2015/11/24 HTML / CSS
新闻网站实习自我鉴定
2013/09/25 职场文书
银行会计业务的个人自我评价
2013/11/02 职场文书
外贸销售员求职的自我评价
2013/11/23 职场文书
函授生自我鉴定
2014/03/25 职场文书
相亲大会策划方案
2014/06/05 职场文书
优秀员工推荐材料
2014/12/20 职场文书
公司市场部岗位职责
2015/04/15 职场文书
早恋主题班会
2015/08/14 职场文书
数据结构课程设计心得体会
2016/01/15 职场文书
只需要12页,掌握撰写一流商业计划书的技巧
2019/05/07 职场文书
教你怎么用Python selenium操作浏览器对象的基础API
2021/06/23 Python
为了顺利买到演唱会的票用Python制作了自动抢票的脚本
2021/10/16 Python
Win11如何设置右键单击显示所有选项?Win11右键单击显示所有选项设置教程
2022/04/08 数码科技