当前位置:首页 > PHP教程 > php面向对象 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2021-11-22 13:55:21 浏览: 评论:0 

这篇文章主要介绍了PHP抽象类与接口的区别,结合实例形式分析了php抽象类与接口的概念、区别、使用方法及相关操作注意事项,需要的朋友可以参考下。

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

抽象类abstract

概念

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

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

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

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

特点

抽象类继承,使用关键字extends。

抽象类可以声明各种变量、常量、方法。

抽象类可以有构造函数。

抽象类中的方法可以是公开的public、保护的protected、私有的private。

一个类只能继承一个抽象类。

示例

示例一

  1. <?php 
  2. // 抽象类 
  3. abstract class AbstractClasss 
  4.   // 强制要求子类定义这些方法 
  5.   abstract protected function getValue(); 
  6.   abstract protected function prefixValue(); 
  7.   // 普通方法(非抽象方法) 
  8.   public function printOut()  
  9.   { 
  10.     print $this->getValue() . "\n"
  11.   } 
  12. // 子类 
  13. class ConcreteClassOne extends AbstractClass 
  14.   protected function getValue() 
  15.   { 
  16.     return "ConcreteClassOne"
  17.   } 
  18.   public function prefixValues($prefix
  19.   { 
  20.     return "{$prefix}ConcreteClassOne"
  21.   } 
  22. // 子类 
  23. class ConcreteClassTwo extends AbstractClass 
  24.   protected function getValue() 
  25.   { 
  26.     return "ConcreteClassTwo"
  27.   } 
  28.   public function prefixValue($prefix
  29.   { 
  30.     return "{$prefix}ConcreteClassTwo"
  31.   } 
  32. // 实例化第一个子类 
  33. $classOne = new ConcreteClassOne; 
  34. $classOne->printOut(); 
  35. echo $classOne->prefixValue('FOO_') . "\n"
  36. // 实例化第二个子类 
  37. $classTwo = new ConcreteClassTwo; 
  38. $classTwo->printOut(); 
  39. echo $classTwo->prefixValue('FOO_') . "\n"

结果输出

ConcreteClassOne

FOO_ConcreteClassOne

ConcreteClassTwo

FOO_ConcreteClassTwo

示例二

  1. <?php 
  2. // 抽象类 
  3. abstract class AbstractClass 
  4.   // 我们的抽象方法仅需要定义需要的参数 
  5.   abstract protected function prefixName($name); 
  6. // 子类 
  7. class ConcreteClass extends AbstractClass 
  8.   // 我们的子类可以定义父类签名中不存在的可选参数 
  9.   public function prefixName($name$separator = "."
  10.   { 
  11.     if ($name == "Pacman") { 
  12.       $prefix = "Mr"
  13.     } elseif ($name == "Pacwoman") { 
  14.       $prefix = "Mrs"
  15.     } else { 
  16.       $prefix = ""
  17.     } 
  18.     return "{$prefix}{$separator} {$name}"
  19.   } 
  20. // 实例化子类 
  21. $class = new ConcreteClass; 
  22. echo $class->prefixName("Pacman") . "\n"
  23. echo $class->prefixName("Pacwoman") . "\n"

结果输出

Mr. Pacman

Mrs, Pacwoman

接口interface

概念

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

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

特点

接口的实现,使用关键字implements。

接口中不能声明变量,但是可以声明常量。

接口中没有构造函数。

接口中的方法默认都是公开的public。

一个类可以实现多个接口。

示例

示例一 、 实现接口

  1. <?php 
  2. // 声明一个iTemplate接口 
  3. interface iTemplate 
  4.   public function setVariable($name$var); 
  5.   public function getHtml($template); 
  6. // 实现接口 
  7. // 下面的写法是正确的 
  8. class Template implements iTemplate 
  9.   private $vars = array(); 
  10.   public function setVariable($name$var
  11.   { 
  12.     $this->vars[$name] = $var
  13.   } 
  14.   public function getHtml($template
  15.   { 
  16.     foreach($this->vars as $name => $value) { 
  17.       $template = str_replace('{' . $name . '}'$value$template); 
  18.     } 
  19.     return $template
  20.   } 
  21. // 下面的写法是错误的,会报错,因为没有实现 getHtml() 
  22. // Fatal error: Class BadTemplate contains 1 abstract methonds 
  23. // and must therefore be declared abstaract (iTemplate::getHtml) 
  24. class BadTemplate implements iTemplate 
  25.   private $vars = array(); 
  26.   public function setVariable($name$var
  27.   { 
  28.     $this->vars[$name] = $var
  29.   } 

示例二 、 可扩充接口

  1. <?php 
  2. interface a 
  3.   public function foo(); 
  4. interface b extends a 
  5.   public function baz(Baz $baz); 
  6. // 正确的写法 
  7. class c implements b 
  8.   public function foo() 
  9.   { 
  10.   } 
  11.   public function baz(Baz $baz
  12.   { 
  13.   } 
  14. // 错误的写法会导致一个致命的错误 
  15. class d implements b 
  16.   public function foo() 
  17.   { 
  18.   } 
  19.   public function baz(Foo $foo
  20.   { 
  21.   } 

示例三 、 继承多个接口

  1. <?php 
  2. interface a 
  3.   pubLic function foo(); 
  4. interface b 
  5.   public function bar(); 
  6. interface c extends a, b 
  7.   public function baz(); 
  8. class d implements c 
  9.   public function foo() 
  10.   { 
  11.   } 
  12.   public function bar() 
  13.   { 
  14.   } 
  15.   public function baz() 
  16.   { 
  17.   } 

示例四 、使用接口常量

  1. <?php 
  2. interface a 
  3.   const b = 'Interface constant'
  4. // 输出接口变量 
  5. echo a:b; 
  6. // 错误的写法,因为常量不能被覆盖。 
  7. // 接口常量的概念和类常量的是一样的。 
  8. class b implements a 
  9.   const b = 'Class constant' 
  10. }

Tags: PHP抽象类 PHP接口

分享到: