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

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

发布:smiling 来源: PHP粉丝网  添加日期:2022-06-25 11:05:30 浏览: 评论:0 

这篇文章主要介绍了PHP 使用 Trait 解决 PHP 单继承问题,结合实例形式详细分析了PHP 使用 Trait 实现PHP单继承的相关操作技巧与注意事项,需要的朋友可以参考下。

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

什么是继承?

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

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

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

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

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

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

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

PHP的单继承示例:

  1. // 单继承:一个子类只能有一个父类 
  2.  
  3. class A{ 
  4.  
  5.   function show() { 
  6.  
  7.     echo "A"; 
  8.  
  9.   } 
  10.  
  11. } 
  12.  
  13.    
  14.  
  15. class B{ 
  16.  
  17.   function show() { 
  18.  
  19.     echo "B"; 
  20.  
  21.   } 
  22.  
  23. } 
  24.  
  25.    
  26.  
  27. class C extends A{ 
  28.  
  29.    
  30.  
  31. } 
  32.  
  33.    
  34.  
  35. $c = new C; 
  36.  
  37. $c->show(); 

使用Trait解决PHP的单继承

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

Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 methodTrait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题无法通过 trait 自身来实例化

示例:

  1. <?php 
  2.  
  3.   trait Reader{ 
  4.  
  5.    public function add($var1,$var2){ 
  6.  
  7.      return $var1+$var2; 
  8.  
  9.    } 
  10.  
  11.   } 
  12.  
  13.   trait writer { 
  14.  
  15.    public function multiplication($var1,$var2){ 
  16.  
  17.      return $var1*$var2; 
  18.  
  19.    } 
  20.  
  21.   } 
  22.  
  23.   class File { 
  24.  
  25.    use Reader; 
  26.  
  27.    use writer; 
  28.  
  29.    public function calculate($var1,$var2){ 
  30.  
  31.      echo "Ressult of addition:".$this->add($var1,$var2) ."\n"; 
  32.  
  33.      echo "Ressult of multiplication:".$this->multiplication($var1,$var2); 
  34.  
  35.    } 
  36.  
  37.   } 
  38.  
  39.   $o = new File(); 
  40.  
  41.   $o->calculate(5,3); 

多个trait

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

  1. <?php 
  2.  
  3. trait Hello { 
  4.  
  5.   public function sayHello() { 
  6.  
  7.     echo 'Hello '; 
  8.  
  9.   } 
  10.  
  11. } 
  12.  
  13.    
  14.  
  15. trait World { 
  16.  
  17.   public function sayWorld() { 
  18.  
  19.     echo 'World'; 
  20.  
  21.   } 
  22.  
  23. } 
  24.  
  25.    
  26.  
  27. class MyHelloWorld { 
  28.  
  29.   use Hello, World; 
  30.  
  31.   public function sayExclamationMark() { 
  32.  
  33.     echo '!'; 
  34.  
  35.   } 
  36.  
  37. } 
  38.  
  39.    
  40.  
  41. $o = new MyHelloWorld(); 
  42.  
  43. $o->sayHello(); 
  44.  
  45. $o->sayWorld(); 
  46.  
  47. $o->sayExclamationMark(); 

冲突的解决

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

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

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

示例:

  1. <?php 
  2.  
  3. trait A { 
  4.  
  5.   public function smallTalk() { 
  6.  
  7.     echo 'a'; 
  8.  
  9.   } 
  10.  
  11.   public function bigTalk() { 
  12.  
  13.     echo 'A'; 
  14.  
  15.   } 
  16.  
  17. } 
  18.  
  19.    
  20.  
  21. trait B { 
  22.  
  23.   public function smallTalk() { 
  24.  
  25.     echo 'b'; 
  26.  
  27.   } 
  28.  
  29.   public function bigTalk() { 
  30.  
  31.     echo 'B'; 
  32.  
  33.   } 
  34.  
  35. } 
  36.  
  37.    
  38.  
  39. class Talker { 
  40.  
  41.   use A, B { 
  42.  
  43.     B::smallTalk insteadof A; 
  44.  
  45.     A::bigTalk insteadof B; 
  46.  
  47.   } 
  48.  
  49. } 
  50.  
  51.    
  52.  
  53. class Aliased_Talker { 
  54.  
  55.   use A, B { 
  56.  
  57.     B::smallTalk insteadof A; 
  58.  
  59.     A::bigTalk insteadof B; 
  60.  
  61.     B::bigTalk as talk; 
  62.  
  63.   } 
  64.  
  65. } 

从trait 来组成trait

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

  1. <?php 
  2.  
  3. trait Hello { 
  4.  
  5.   public function sayHello() { 
  6.  
  7.     echo 'Hello '; 
  8.  
  9.   } 
  10.  
  11. } 
  12.  
  13.    
  14.  
  15. trait World { 
  16.  
  17.   public function sayWorld() { 
  18.  
  19.     echo 'World!'; 
  20.  
  21.   } 
  22.  
  23. } 
  24.  
  25.    
  26.  
  27. trait HelloWorld { 
  28.  
  29.   use Hello, World; 
  30.  
  31. } 
  32.  
  33.    
  34.  
  35. class MyHelloWorld { 
  36.  
  37.   use HelloWorld; 
  38.  
  39. } 
  40.  
  41.    
  42.  
  43. $o = new MyHelloWorld(); 
  44.  
  45. $o->sayHello(); 
  46.  
  47. $o->sayWorld(); 

Trait的抽象成员

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

  1. <?php 
  2.  
  3. trait Hello { 
  4.  
  5.   public function sayHelloWorld() { 
  6.  
  7.     echo 'Hello'.$this->getWorld(); 
  8.  
  9.   } 
  10.  
  11.   abstract public function getWorld(); 
  12.  
  13. } 
  14.  
  15.    
  16.  
  17. class MyHelloWorld { 
  18.  
  19.   private $world; 
  20.  
  21.   use Hello; 
  22.  
  23.   public function getWorld() { 
  24.  
  25.     return $this->world; 
  26.  
  27.   } 
  28.  
  29.   public function setWorld($val) { 
  30.  
  31.     $this->world = $val; 
  32.  
  33.   } 
  34.  
  35. } 

Trait的静态成员

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

  1. <?php<br>// 静态成员 
  2.  
  3. trait Counter { 
  4.  
  5.   public function inc() { 
  6.  
  7.     static $c = 0; 
  8.  
  9.     $c = $c + 1; 
  10.  
  11.     echo "$c\n"; 
  12.  
  13.   } 
  14.  
  15. }
  16.    
  17.  
  18. class C1 { 
  19.  
  20.   use Counter; 
  21.  
  22. } 
  23.  
  24.    
  25.  
  26. class C2 { 
  27.  
  28.   use Counter; 
  29.  
  30. } 
  31.  
  32. $o = new C1(); $o->inc(); // echo 1 
  33.  
  34. $p = new C2(); $p->inc(); // echo 1 
  35.  
  36.  
  37. <?php 
  38.  
  39. // 静态方法 
  40.  
  41. trait StaticExample { 
  42.  
  43.   public static function doSomething() { 
  44.  
  45.     return 'Doing something'; 
  46.  
  47.   } 
  48.  
  49. } 
  50.  
  51.    
  52.  
  53. class Example { 
  54.  
  55.   use StaticExample; 
  56.  
  57. } 
  58.  
  59.    
  60.  
  61. Example::doSomething();
  62.  
  63. <?php 
  64.  
  65. // 定义属性 
  66.  
  67. trait PropertiesTrait { 
  68.  
  69.   public $x = 1; 
  70.  
  71. } 
  72.  
  73.    
  74.  
  75. class PropertiesExample { 
  76.  
  77.   use PropertiesTrait; 
  78.  
  79. } 
  80.  
  81.    
  82.  
  83. $example = new PropertiesExample; 
  84.  
  85. $example->x;

Tags: Trait PHP单继承

分享到: