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之间的冲突