PHP中的Trait 特性及作用
自PHP5.4.0起,PHP实现了代码复用的一个方法,称为traits。
Traits是一种为类似PHP的单继承语言而准备的代码复用机制。Trait为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集。Traits和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题。
Trait和一个类相似,但仅仅旨在用细粒度和一致的方式来组合功能。Trait不能通过它自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用类的成员不需要继承。
Trait是在PHP5.4中加入的,它既不是接口也不是类。主要是为了解决单继承语言的限制。是PHP多重继承的一种解决方案。例如,需要同时继承两个AbstractClass,这将会是件很麻烦的事情,Trait就是为了解决这个问题。它能被加入到一个或多个已经存在的类中。它声明了类能做什么(表明了其接口特性),同时也包含了具体实现(表明了其类特性)
简单使用
首先,当然是声明个Trait,PHP5.4增加了trait关键字
traitfirst_trait{ functionfirst_method(){/*CodeHere*/} functionsecond_method(){/*CodeHere*/} }
同时,如果要在Class中使用该Trait,那么使用use关键字
classfirst_class{ //注意这行,声明使用first_trait usefirst_trait; } $obj=newfirst_class(); //Executingthemethodfromtrait $obj->first_method();//valid $obj->second_method();//valid
使用多个Trait
在同个Class中可以使用多个Trait
traitfirst_trait { functionfirst_method(){echo"method";} } traitsecond_trait{ functionsecond_method(){echo"method";} } classfirst_class{ //nowusingmorethanonetrait usefirst_trait,second_trait; } $obj=newfirst_class(); //Valid $obj->first_method();//Print:method //Valid $obj->second_method();//Print:method
Trait之间的嵌套
同时,Trait之间也可以相互的嵌套,例如
traitfirst_trait{ functionfirst_method(){echo"method";} } traitsecond_trait{ usefirst_trait; functionsecond_method(){echo"method";} } classfirst_class{ //nowusing usesecond_trait; } $obj=newfirst_class(); //Valid $obj->first_method();//Print:method //Valid $obj->second_method();//Print:method
Trait的抽象方法(AbstractMethod)
我们可以在Trait中声明需要实现的抽象方法,这样能使使用它的Class必须实现它
traitfirst_trait{ functionfirst_method(){echo"method";} //这里可以加入修饰符,说明调用类必须实现它 abstractpublicfunctionsecond_method(); } classfirst_method{ usefirst_trait; functionsecond_method(){ /*CodeHere*/ } }
Trait冲突
多个Trait之间同时使用难免会冲突,这需要我们去解决。PHP5.4从语法方面带入了相关的关键字语法:insteadof以及as,用法参见
traitfirst_trait{ functionfirst_function(){ echo"FromFirstTrait"; } } traitsecond_trait{ //这里的名称和first_trait一样,会有冲突 functionfirst_function(){ echo"FromSecondTrait"; } } classfirst_class{ usefirst_trait,second_trait{ //在这里声明使用first_trait的first_function替换 //second_trait中声明的 first_trait::first_functioninsteadofsecond_trait; } } $obj=newfirst_class(); //Output:FromFirstTrait $obj->first_function();
上面就是些Trait比较基本的使用了,更详细的可以参考官方手册。这里总结下注意的几点:
Trait会覆盖调用类继承的父类方法
Trait无法如Class一样使用new实例化
单个Trait可由多个Trait组成
在单个Class中,可以使用多个Trait
Trait支持修饰词(modifiers),例如final、static、abstract
我们能使用insteadof以及as操作符解决Trait之间的冲突