因为php是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php在5.4后出了Trait这个特性。
php原文:Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。
看实例:
1.
trait Dog{ public $name = 'Dog'; public function drive(){ echo 'This is trait dog drive'; } public function eat(){ echo 'This is trait dog eat'; } } class Animal{ public function drive(){ echo 'This is class animal drive'; } public function eat(){ echo 'This is class animal eat'; } } class Cat extends Animal{ use Dog; public function drive(){ echo 'This is class cat drive'; } } $cat = new Cat(); $cat->drive(); echo "<br>"; $cat->eat(); //输出 //This is class cat drive //This is trait dog eat //结论:基类可以重写/调用trait同名的属性或方法;
2.
trait trait1{ public function eat(){ echo "This is trait1 eat"; } public function drive(){ echo "This is trait1 drive"; } } trait trait2{ public function eat(){ echo "This is trait2 eat"; } public function drive(){ echo "This is trait2 drive"; } } class cats{ use trait1,trait2{ trait1::eat insteadof trait2; trait1::drive insteadof trait2; } } class dogs{ use trait1,trait2{ trait1::eat insteadof trait2; trait1::drive insteadof trait2; trait2::eat as eaten; trait2::drive as driven; } } $cats = new cats(); $cats->eat(); echo "<br>"; $cats->drive(); echo "<br>"; echo "<br>"; echo "<br>"; $dogs = new dogs(); $dogs->eat(); echo "<br>"; $dogs->drive(); echo "<br>"; $dogs->eaten(); echo "<br>"; $dogs->driven(); //输出 //This is trait1 eat //This is trait1 drive //This is trait1 eat //This is trait1 drive //This is trait2 eat //This is trait2 drive //结论:多trait可以使用,间隔;当不同的trait调用时,有着相同的属性或方法,会产生冲突,可以使用insteadof(进行替代),或者as(对其取别名)
3.
trait Animal{ public function eat(){ echo "This is Animal eat"; } } class Dog{ use Animal{ eat as protected; } } class Cat{ use Animal{ Animal::eat as private eaten; } } $dog = new Dog(); //$dog->eat();//报错,因为已经把eat改成了保护 $cat = new Cat(); $cat->eat();//正常运行,不会修改原先的访问控制 $cat->eaten();//报错,已经改成了私有的访问控制 //结论:as可以修改方法的访问控制
4.
trait Cat{ public function eat(){ echo "This is Cat eat"; } } trait Dog{ use Cat; public function drive(){ echo "This is Dog drive"; } abstract public function getName(); public function test(){ static $num=0; $num++; echo $num; } public static function say(){ echo "This is Dog say"; } } class animal{ use Dog; public function getName(){ echo "This is animal name"; } } $animal = new animal(); $animal->getName(); echo "<br/>"; $animal->eat(); echo "<br/>"; $animal->drive(); echo "<br/>"; $animal::say(); echo "<br/>"; $animal->test(); echo "<br/>"; $animal->test(); echo "<br/>"; $animal->test(); //输出 //This is animal name //This is Cat eat //This is Dog drive //This is Dog say //1 //2 //3 //结论:Trait也可以互相组合,还可以使用抽象方法,静态属性,静态方法等
来源: