由于 PHP 是单继承语言,因此使用 trait 来实现了类似多继承的代码复用,一个 trait 和一个类相似,但 trait 不能像类一个实例化,而是通过关键字use
添加到其它类的内部,相比于传统继承方法,trait 增加了水平特性的组合。
引入了 trait 类的调用顺序依次为:当前类 ==> trait ==> 父类。
在 trait 中,可以使用抽象方法、静态变量与静态方法,在 trait 中同样可以定义属性。
如果在引入的不同 trait 中包含了同名方法,则需要使用 insteadof
关键字或as
关键字来避免冲突,前者是声明排除掉其它方法,后者则是对冲突的方法名重命名,与命名空间中的as
作用相同,建议使用as
关键字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| <?php class Base { public function hello() { echo 'method hello from class Base'; } }
trait Hello { public function hello() { echo 'method hello from Trait Hello!'; }
public function hi() { echo 'method hi from Trait Hello!'; }
abstract public function getValue();
public static function staticMethod() { echo 'static method staticMethod from Trait Hello!'; }
public function staticValue() { static $value; $value++; echo $value; } }
trait Hi { public function hello() { echo 'method hello from Trait Hi!'; }
public function hi() { echo 'method hi from Trait Hi!'; } }
trait HelloHi { use Hello, Hi { Hello::hello insteadOf Hi; Hi::hi insteadOf Hello; } }
class MyNew extends Base { use HelloHi;
private $value = 'class MyNew'; public function getValue() { return $this->value; } }
$obj = new MyNew(); $obj->hello(); $obj->hi(); MyNew::staticMethod(); echo $obj->getValue(); $objOther = new MyNew(); $obj->staticValue(); $objOther->staticValue();
|
参考资料
- Trait - PHP Manual
- Laravel 框架关键技术解析 3.6 节