php中的trait

转载 2016年08月21日 23:02:59
 

php中的trait

PHP5.4起,新增一种新的代码复用的方法,trait。PHP与JAVA类似,与C++不同,是一种单继承语言,PHP引入trait,可以减少单继承语言的限制,使开发人员能够自由地在不同的层次结构内独立的类中复用method。Trait和Class组合的语义定义了一种减少复杂性的方式,避免传统多继承和Mixin类相关经典问题,例如C++中的钻石危机(也称棱形问题):
  1. 如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。
  2. 如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。

Trait和Class相似,但仅仅旨在用细粒度和一致的方式来组合功能。无法通过trait自身来实例化。它为传统继承增加了水平特性的组合。

Trait使用case

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2.   
  3. trait Mytrait {  
  4.     public $a = 100;  
  5.     public function test1() {  
  6.         echo "Mytrait Test1\n";  
  7.     }     
  8.     public static function test2() {  
  9.         echo "Mytrait Test2\n";  
  10.     }     
  11.   
  12. }  
  13.   
  14. class TraitExample1 {  
  15.     use Mytrait;  
  16. }  
  17.   
  18. $obj = new TraitExample1();  
  19. $obj->test1();  
  20. TraitExample1::test2();  
  21. echo $obj->a . "\n";  

优先级

对于方法:
当前类的成员>trait的方法>从基类继承的成员

对于变量:
当前类和基类中不能存在与trait重名的变量,否则会抛出fatal error。


[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2.   
  3. trait Mytrait {  
  4.     public $a = 100;  
  5.     public function test1() {  
  6.         echo "Mytrait Test1\n";  
  7.     }     
  8.     public static function test2() {  
  9.         echo "Mytrait Test2\n";  
  10.     }     
  11.   
  12. }  
  13. class Base {  
  14.     public function test1() {  
  15.         echo "Base Test1\n";  
  16.     }     
  17.     public static function test2() {  
  18.         echo "Base Test2\n";  
  19.     }     
  20.     public static function test3() {  
  21.         echo "Base Test3\n";  
  22.     }     
  23.       
  24. }  
  25. class TraitExample1 extends Base{  
  26.     use Mytrait;  
  27.     public function test1() {  
  28.         echo "TraitExample1 Test1\n";  
  29.     }     
  30.   
  31. }  
  32.   
  33. $obj = new TraitExample1();  
  34. $obj->test1();  
  35. TraitExample1::test2();  
  36. $obj->test3();  
  37. echo $obj->a . "\n";  

多个trait

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

如果两个trait都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。为了解决多个trait在同一个类中的命名冲突,需要使用insteadof操作符来明确指定使用冲突方法中的哪一个。或者使用as操作符,可以将其中一个冲突的方法以另一个名称来引入。

同样的,如果两个trait有同名的变量,如果该属性的定义兼容(同样的可见性及初始值)错误级别是E_STRICT,否则错误级别是E_ERROR.

且不能通过解决方法冲突的方式解决。

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2.   
  3. trait Mytrait {  
  4.     public $a = 100;  
  5.     public function test1() {  
  6.         echo "Mytrait Test1\n";  
  7.     }     
  8.     public static function test2() {  
  9.         echo "Mytrait Test2\n";  
  10.     }     
  11.   
  12. }  
  13. trait Mytrait2 {  
  14.     public function test1() {  
  15.         echo "Mytrait2 Test1\n";  
  16.     }     
  17.     public static function test2() {  
  18.         echo "Mytrait2 Test2\n";  
  19.     }     
  20.   
  21. }  
  22. class TraitExample1{  
  23.     use Mytrait,Mytrait2 {  
  24.         Mytrait::test1 insteadof Mytrait2;  
  25.         Mytrait2::test2 insteadof Mytrait;  
  26.         Mytrait::test2 as test2_2;  
  27.     }     
  28. }  
  29.   
  30. $obj = new TraitExample1();  
  31. $obj->test1();  
  32. TraitExample1::test2();  
  33. $obj->test2_2();  
  34. echo $obj->a . "\n";  

修改方法的访问控制

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2.   
  3. trait Mytrait {  
  4.     public function test1() {  
  5.         echo "Mytrait Test1\n";  
  6.     }     
  7.     public function test2() {  
  8.         echo "Mytrait Test2\n";  
  9.     }     
  10.     private function test3() {  
  11.         echo "Mytrait Test3\n";  
  12.     }     
  13.   
  14. }  
  15. class TraitExample1{  
  16.     use Mytrait {  
  17.         test1 as protected;  
  18.         test2 as public test2_1;  
  19.         test3 as public;  
  20.     }     
  21. }  

指定alias会创建一个新的方法,原方法访问控制权限不变。不仅可以缩小权限的方向修改(public->private),也可以向放大权限的修改(private->public).


从trait来组成trait

与Class中使用多个trait类似,trait也可以使用多个trait。冲突的解决方式也一致。

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2.   
  3. trait Mytrait {  
  4.     public function test1() {  
  5.         echo "Mytrait Test1\n";  
  6.     }     
  7.     public function test2() {  
  8.         echo "Mytrait Test2\n";  
  9.     }     
  10.   
  11. }  
  12. trait Mytrait2 {  
  13.     public function test1() {  
  14.         echo "Mytrait2 Test1\n";  
  15.     }     
  16.     public function test2() {  
  17.         echo "Mytrait2 Test2\n";  
  18.     }     
  19.   
  20. }  
  21.   
  22. trait Mytrait3 {  
  23.     use Mytrait, Mytrait2 {  
  24.         Mytrait::test1 insteadof Mytrait2;  
  25.         Mytrait2::test2 insteadof Mytrait;  
  26.     }     
  27. }  
  28. class TraitExample1{  
  29.     use Mytrait3;  
  30. }  
  31.   
  32. $obj = new TraitExample1();  
  33. $obj->test1();  
  34. $obj->test2();  

Trait的抽象成员

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

Trait的静态成员

trait可以定义静态变量,静态方法。

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2.   
  3. trait Mytrait {  
  4.     public static $in = 10;   
  5.     public function test1() {  
  6.         echo "Mytrait Test1\n";  
  7.     }     
  8.     public function test2() {  
  9.         echo "Mytrait Test2\n";  
  10.     }     
  11.   
  12. }  
  13. trait Mytrait2 {  
  14.     public function test1() {  
  15.         echo "Mytrait2 Test1\n";  
  16.     }     
  17.     public static function test2() {  
  18.         echo "Mytrait2 Test2\n";  
  19.     }     
  20.   
  21. }  
  22.   
  23. trait Mytrait3 {  
  24.     use Mytrait, Mytrait2 {  
  25.         Mytrait::test1 insteadof Mytrait2;  
  26.         Mytrait::test2 insteadof Mytrait2;  
  27.         Mytrait2::test2 as test3;  
  28.     }     
  29. }  
  30. class TraitExample1{  
  31.     use Mytrait3;  
  32. }  
  33.   
  34. $obj = new TraitExample1();  
  35. $obj->test1();  
  36. $obj->test2();  
  37. TraitExample1::test3();  
  38. [root@hadoop1 php]# cat trait2.php      
  39. <?php  
  40.   
  41. trait Mytrait {  
  42.         public static $in = 10;  
  43.         public function test1() {  
  44.                 echo "Mytrait Test1\n";  
  45.         }  
  46.         public function test2() {  
  47.                 echo "Mytrait Test2\n";  
  48.         }  
  49.   
  50. }  
  51. trait Mytrait2 {  
  52.         public function test1() {  
  53.                 echo "Mytrait2 Test1\n";  
  54.         }  
  55.         public static function test2() {  
  56.                 echo "Mytrait2 Test2\n";  
  57.         }  
  58.   
  59. }  
  60.   
  61. trait Mytrait3 {  
  62.         use Mytrait, Mytrait2 {  
  63.                 Mytrait::test1 insteadof Mytrait2;  
  64.                 Mytrait::test2 insteadof Mytrait2;  
  65.                 Mytrait2::test2 as test3;  
  66.         }  
  67. }  
  68. class TraitExample1{  
  69.         use Mytrait3;  
  70. }  
  71.   
  72. $obj = new TraitExample1();  
  73. $obj->test1();  
  74. $obj->test2();  
  75. TraitExample1::test3();  
  76. echo TraitExample1::$in;  











相关文章推荐

PHP 5.4 的 Trait 特性_实现类的多重继承

Trait 是 PHP5.4 中的新特性,是 PHP 多重继承的一种解决方案。例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情,Trait 就是为了解决这个问题。基本使用...

PHP:代码复用trait

PHP实现了代码复用的一个方法,称为trait。 通常情况下,当我们需要在多个不同的类使用同一个方法的时候,继承是不错的解决方法。但是,在PHP中,每个类只能从单一的父类继承,这样的话,就不能设计一个...

Php学习之trait的使用

说通俗点,PHP中使用trait关键字是为了解决一个类既想集成基类的属性和方法,又想拥有别的基类的方法,而trait一般情况下是和use搭配使用的。本文和大家分享的就是php中trait使用相关内容,...

php-Trait

概述 自PHP 5.4.0 起, PHP 实现了一种代码复用的方法,称为 trait. 作用 Trait是为类似 PHP 的单继承语言而准备的一种代码复用机制。 Trait为了减少单继承...

php Trait 基础应用讲解

首先,上手册:自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。随后。。。来讲解trait的用法:trait first_trait { function fir...

什么是php的性状(Trait)

很多PHP开发朋友都没有弄清楚Trait(性状)。这是PHP5.4.0引入的新概念,既像类又像接口。性状是类的补分实现(即常量、属性、方法),可以混入一个或者多个现有的PHP类中。 性状有两个作用:表...

【多继承】PHP使用trait或者是组合的模式来实现多继承【原创】

PHP的类继承只能是单继承,不能多继承,如果想要实现多继承的话,可以使用接口的方式来多继承,但是如果不想使用接口的方式来实现多继承的话,可以考虑使用trait来实现,当然也可以使用组合模式来实现。...

PHP 代码复用trait

自PHP 5.4.0起,PHP实现了一种代码服用的方法,称为trait。Trait是为类似PHP的单继承语言而准备的一种代码复用机制。Trait为了减少单继承语言的限制,使开发人员能够自由地在不同层次...
  • dgh_84
  • dgh_84
  • 2017年01月27日 01:27
  • 299

PHP中Trait特性

Trait是自 PHP 5.4.0 起添加的一个新特性,是 PHP 多重继承的一种解决方案。例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情,Trait 就是为了解决这个...
  • ylhalo
  • ylhalo
  • 2017年06月05日 14:49
  • 81

PHP基础补全系列:Trait

这个系列的文章是用来学习PHP的一些不常用的语法特性,用来加强自己对PHP语法特性的理解。在大多数情况下都是作为自己的学习笔记,文章内容不会超出PHP手册,所以想了解相关特性的可以直接去看PHP手册。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:php中的trait
举报原因:
原因补充:

(最多只允许输入30个字)