当前位置:首页 > 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.   // 强制要求子类定义这些方法 
  6.   abstract protected function getValue(); 
  7.   abstract protected function prefixValue(); 
  8.   // 普通方法(非抽象方法) 
  9.   public function printOut()  
  10.   { 
  11.     print $this->getValue() . "\n"; 
  12.   } 
  13. } 
  14. // 子类 
  15. class ConcreteClassOne extends AbstractClass 
  16. { 
  17.   protected function getValue() 
  18.   { 
  19.     return "ConcreteClassOne"; 
  20.   } 
  21.   public function prefixValues($prefix) 
  22.   { 
  23.     return "{$prefix}ConcreteClassOne"; 
  24.   } 
  25. } 
  26. // 子类 
  27. class ConcreteClassTwo extends AbstractClass 
  28. { 
  29.   protected function getValue() 
  30.   { 
  31.     return "ConcreteClassTwo"; 
  32.   } 
  33.   public function prefixValue($prefix) 
  34.   { 
  35.     return "{$prefix}ConcreteClassTwo"; 
  36.   } 
  37. } 
  38. // 实例化第一个子类 
  39. $classOne = new ConcreteClassOne; 
  40. $classOne->printOut(); 
  41. echo $classOne->prefixValue('FOO_') . "\n"; 
  42. // 实例化第二个子类 
  43. $classTwo = new ConcreteClassTwo; 
  44. $classTwo->printOut(); 
  45. echo $classTwo->prefixValue('FOO_') . "\n"; 

结果输出

ConcreteClassOne

FOO_ConcreteClassOne

ConcreteClassTwo

FOO_ConcreteClassTwo

示例二

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

结果输出

Mr. Pacman

Mrs, Pacwoman

接口interface

概念

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

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

特点

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

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

接口中没有构造函数。

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

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

示例

示例一 、 实现接口

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

示例二 、 可扩充接口

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

示例三 、 继承多个接口

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

示例四 、使用接口常量

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

Tags: PHP抽象类 PHP接口

分享到: