Trait
PHP 实现了一种代码复用的方法,称为trait。
Trait是类似PHP的单继承语言而准备的一种代码复用机制。Trait为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用method。Trait和Class组合的语义定义了一种减少复杂性的方式,避免传统多继承和Mixin类相关典型问题。
Trait和Class相似,但仅仅旨在用细粒度和一致的方式来组合功能。无法通过trait自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个Class之间不需要继承。
示例:
<?php
trait ezcReflectionReturnInfo {
function getReturnType() { /*1*/ }
function getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod {
use ezcReflectionReturnInfo;
/* ... */
}
class ezcReflectionFunction extends ReflectionFunction {
use ezcReflectionReturnInfo;
/* ... */
}
?>
优先级
从基类继承的成员会被trait插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了trait的方法,而trait则覆盖了被继承的方法。
多个trait
通过逗号分隔,在use声明列出多个trait,可以都插入到一个类中。
冲突的解决
如果两个trait都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。
为了解决多个trait在同一个类中的命名冲突,需要使用insteadof操作符来明确指定使用冲突方法中的哪一个。
以上方法仅允许排除掉其他方法,as操作符可以为某个方法引入别名。
注意,as操作符不会对方法进行重命名,也不会影响其方法。
修改方法的访问控制
使用as语法还可以用来调整方法的访问控制。
从trait来组成trait
正如class能够使用trait一样,其他trait也能够使用trait。在trait定义时通过使用一个或多个trait,能够组合其他trait中的部分或全部成员。
Trait的抽象成员
为了对使用的类施加强制要求,trait支持抽象方法的使用。
Trait的静态成员
Trait可以被静态成员静态方法定义。
属性
Trait同样可以定义属性。
Trait定义了一个属性后,类就不能定义同样名称的属性,否则会产生fatal error。有种情况例外:属性是兼容的(同样的访问可见度、初始默认值)。