当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP 使用 Trait 解决 PHP 单继承问题详解

发布:smiling 来源: PHP粉丝网  添加日期:2022-03-01 09:21:06 浏览: 评论:0 

本文实例讲述了PHP 使用 Trait 解决 PHP 单继承问题,分享给大家供大家参考,具体如下:

什么是继承?

继承实际上是存在于面向对象程序设计中的两个类之间的一种关系,是面向对象程序设计方法的一个重要手段,通过继承可以更有效地组织程序结构,明确类间的关系,充分利用已有的类来完成更复杂、更深入的开发。

当一个类拥有另一个类的所有数据和操作时,就称这两个类之间具有继承关系。

被继承的类称为父类,继承了父类的所有数据和操作的类称为子类。

在 PHP 中用 extends 表明子类与父类的继承关系。

在面向对象的程序设计中,采用继承的方式来组织设计系统中的类,可以提高程序的抽象程度,更接近人的思维方式,使程序结构更清晰并降低编码和维护的工作量。

单继承是指任何一个类都只有一个单一的父类,其结构可以用单纯的树状结构来表示;

多继承是指一个类可以有一个以上的父类,它的静态的数据属性和操作从所有这些父类中继承,其结构应以复杂的网状结构来表示。

PHP 仅支持单继承,而多继承是通过接口或者 Trait 来实现的。

PHP 的单继承示例:

  1. // 单继承:一个子类只能有一个父类 
  2. class A{ 
  3.   function show() { 
  4.     echo "A"
  5.   } 
  6.  
  7. class B{ 
  8.   function show() { 
  9.     echo "B"
  10.   } 
  11.  
  12. class C extends A{ 
  13.  
  14.  
  15. $c = new C; 
  16. $c->show(); 

使用 Trait 解决 PHP 的单继承

自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。

Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制

Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method

Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题

无法通过 trait 自身来实例化

示例:

  1. <?php 
  2.   trait Reader{ 
  3.    public function add($var1,$var2){ 
  4.      return $var1+$var2
  5.    } 
  6.   } 
  7.   trait writer { 
  8.    public function multiplication($var1,$var2){ 
  9.      return $var1*$var2
  10.    } 
  11.   } 
  12.   class File { 
  13.    use Reader; 
  14.    use writer; 
  15.    public function calculate($var1,$var2){ 
  16.      echo "Ressult of addition:".$this->add($var1,$var2) ."\n"
  17.      echo "Ressult of multiplication:".$this->multiplication($var1,$var2); 
  18.    } 
  19.   } 
  20.   $o = new File(); 
  21.   $o->calculate(5,3); 

多个 trait

通过逗号分隔,在 use 声明列出多个 trait,可以都插入到一个类中。

  1. <?php 
  2. trait Hello { 
  3.   public function sayHello() { 
  4.     echo 'Hello '
  5.   } 
  6.  
  7. trait World { 
  8.   public function sayWorld() { 
  9.     echo 'World'
  10.   } 
  11.  
  12. class MyHelloWorld { 
  13.   use Hello, World; 
  14.   public function sayExclamationMark() { 
  15.     echo '!'
  16.   } 
  17.  
  18. $o = new MyHelloWorld(); 
  19. $o->sayHello(); 
  20. $o->sayWorld(); 
  21. $o->sayExclamationMark(); 

冲突的解决

如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。

为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。

以上方式仅允许排除掉其它方法,as 操作符可以 为某个方法引入别名,注意,as 操作符不会对方法进行重命名,也不会影响其方法。

示例:

  1. <?php 
  2. trait A { 
  3.   public function smallTalk() { 
  4.     echo 'a'
  5.   } 
  6.   public function bigTalk() { 
  7.     echo 'A'
  8.   } 
  9.  
  10. trait B { 
  11.   public function smallTalk() { 
  12.     echo 'b'
  13.   } 
  14.   public function bigTalk() { 
  15.     echo 'B'
  16.   } 
  17.  
  18. class Talker { 
  19.   use A, B { 
  20.     B::smallTalk insteadof A; 
  21.     A::bigTalk insteadof B; 
  22.   } 
  23.  
  24. class Aliased_Talker { 
  25.   use A, B { 
  26.     B::smallTalk insteadof A; 
  27.     A::bigTalk insteadof B; 
  28.     B::bigTalk as talk; 
  29.   } 

从 trait 来组成 trait

正如 class 能够使用 trait 一样,其它 trait 也能够使用 trait,在 trait 定义时通过使用一个或多个 trait,能够组合其它 trait 中的部分或全部成员。

  1. <?php 
  2. trait Hello { 
  3.   public function sayHello() { 
  4.     echo 'Hello '
  5.   } 
  6.  
  7. trait World { 
  8.   public function sayWorld() { 
  9.     echo 'World!'
  10.   } 
  11.  
  12. trait HelloWorld { 
  13.   use Hello, World; 
  14.  
  15. class MyHelloWorld { 
  16.   use HelloWorld; 
  17.  
  18. $o = new MyHelloWorld(); 
  19. $o->sayHello(); 
  20. $o->sayWorld(); 

Trait 的抽象成员

为了对使用的类施加强制要求,trait 支持抽象方法的使用。

  1. <?php 
  2. trait Hello { 
  3.   public function sayHelloWorld() { 
  4.     echo 'Hello'.$this->getWorld(); 
  5.   } 
  6.   abstract public function getWorld(); 
  7.  
  8. class MyHelloWorld { 
  9.   private $world
  10.   use Hello; 
  11.   public function getWorld() { 
  12.     return $this->world; 
  13.   } 
  14.   public function setWorld($val) { 
  15.     $this->world = $val
  16.   } 

Trait 的静态成员

Traits 可以被静态成员静态方法定义。

  1. <?php<br data-filtered="filtered">// 静态成员 
  2. trait Counter { 
  3.   public function inc() { 
  4.     static $c = 0; 
  5.     $c = $c + 1; 
  6.     echo "$c\n"
  7.   } 
  8.  
  9. class C1 { 
  10.   use Counter; 
  11.  
  12. class C2 { 
  13.   use Counter; 
  14.  
  15. $o = new C1(); $o->inc(); // echo 1 
  16. $p = new C2(); $p->inc(); // echo 1 
  17.  
  18. <?php 
  19. // 静态方法 
  20. trait StaticExample { 
  21.   public static function doSomething() { 
  22.     return 'Doing something'
  23.   } 
  24.  
  25. class Example { 
  26.   use StaticExample; 

Example::doSomething();

  1. <?php 
  2. // 定义属性 
  3. trait PropertiesTrait { 
  4.   public $x = 1; 
  5.  
  6. class PropertiesExample { 
  7.   use PropertiesTrait; 
  8.  
  9. $example = new PropertiesExample; 
  10. $example->x;

Tags: PHP单继承 Trait单继承

分享到: