PHP代码的多继承 -》 PHP代码复用新的姿势 trait
本文参考: http://php.net/language.oop5.traits
一、什么是trait
从PHP 5.4.0 开始 PHP 实现了一种新的代码复用方式 trait。
二、trait解决了什么问题
trait 的出现是为了解决类似PHP的单继承语言而准备的一种代码复用机制,让开发人员能够在不能层次结构内独立的类中复用 method。
三、跟其它语言相比,trait 有什么 好处
Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。
四、该如何使用trait
- 示例1,如何使用 trait
<?php trait ezcReflectionReturnInfo { function getReturnType() { /*1*/ } function getReturnDescription() { /*2*/ } } class ezcReflectionMethod extends ReflectionMethod { use ezcReflectionReturnInfo; /* ... */ } class ezcReflectionFunction extends ReflectionFunction { use ezcReflectionReturnInfo; /* ... */ } ?>
- 示例2 ,trait 与 class 方法优先级问题
trait 方法会覆盖基类中的方法,当前类中的方法会覆盖 trait 方法
<?php class Base { public function sayHello() { echo 'Hello '; } } trait SayWorld { public function sayHello() { parent::sayHello(); echo "World!\r\n"; } } class MyHelloWorld extends Base { use SayWorld; } class MyNewHelloWorld extends Base{ use SayWorld; public function sayHello(){ echo "Hello sunshine!\r\n"; } } $o = new MyHelloWorld(); $o->sayHello(); $b = new MyNewHelloWorld(); $b->sayHello(); ?>
上面的代码会输出:
- 示例3 同时使用多个 trait 通过逗号分隔,在 use 声明列出多个 trait,可以都插入到一个类中。
<?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World'; } } class MyHelloWorld { use Hello, World; public function sayExclamationMark() { echo '!'; } } $o = new MyHelloWorld(); $o->sayHello(); $o->sayWorld(); $o->sayExclamationMark(); ?>
上面的代码会输出:
- 示例4 冲突的解决
如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。
为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。
<?php trait A { public function smallTalk() { echo 'a'; } public function bigTalk() { echo 'A'; } } trait B { public function smallTalk() { echo 'b'; } public function bigTalk() { echo 'B'; } } class Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; } } class Aliased_Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; B::bigTalk as talk; } } ?>
- 示例5 使用trait来组成trait 正如 class 能够使用 trait 一样,其它 trait 也能够使用 trait。在 trait 定义时通过使用一个或多个 trait,能够组合其它 trait 中的部分或全部成员。
<?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World!'; } } trait HelloWorld { use Hello, World; } class MyHelloWorld { use HelloWorld; } $o = new MyHelloWorld(); $o->sayHello(); $o->sayWorld(); ?>
上面例子会输出:
除了这些特性,trait 还包括 抽象成员 静态成员 静态方法 属性 等特性,可以参考 http://php.net/language.oop5.traits