通过在类中使用 use 关键字:声明要组合的 Trait 名称,具体的 Trait 的声明使用 Trait 关键词,Trait 不能实例化
如下代码实例:
<?php trait Dog{ public $name="dog"; public function bark(){ echo "This is dog"; } } class Animal{ public function eat(){ echo "This is animal eat"; } } class Cat extends Animal{ use Dog; public function drive(){ echo "This is cat drive"; } } $cat = new Cat(); $cat->drive();//输出:This is cat drive echo "
"; $cat->eat();//输出:This is animal eat echo "
"; $cat->bark();//输出:This is dog
如下代码实例:
<?php trait Dog{ public $name="dog"; public function drive(){ echo "This is dog drive"; } public function eat(){ echo "This is dog eat"; } } class Animal{ public function drive(){ echo "This is animal drive"; } public function eat(){ echo "This is animal eat"; } } class Cat extends Animal{ use Dog; public function drive(){ echo "This is cat drive"; } } $cat = new Cat(); $cat->drive(); //This is cat drive echo "
"; $cat->eat(); //注意这里输出的是:This is dog eat
所以:Trait 中的方法或属性会覆盖 基类中的同名的方法或属性,而本类会覆盖Trait中同名的属性或方法
use trait1, trait2
当不同的 trait 中,却有着同名的方法或属性,会产生冲突,可以使用 insteadof
或 as
进行解决,insteadof
是进行替代,而 as
是给它取别名
如下实例:
<?php 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 cat{ use trait1,trait2{ trait1::eat insteadof trait2; trait1::drive insteadof trait2; } } class dog{ use trait1,trait2{ trait1::eat insteadof trait2; trait1::drive insteadof trait2; trait2::eat as eaten; trait2::drive as driven; } } $cat = new cat(); $cat->eat();//输出:This is trait1 eat echo "
"; $cat->drive();//输出:This is trait1 drive echo "
"; echo "
"; echo "
"; $dog = new dog(); $dog->eat();//输出:This is trait1 eat echo "
"; $dog->drive();//输出:This is trait1 drive echo "
"; $dog->eaten();//输出:This is trait2 eat echo "
"; $dog->driven();//输出:This is trait2 driven
<?php 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();//报错,已经改成了私有的访问控制
<?php 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();//输出:This is animal name echo "
"; $animal->eat();//输出:This is Cat eat echo "
"; $animal->drive();//输出:This is Dog drive echo "
"; $animal::say();//输出:This is Dog say echo "
"; $animal->test();//输出:1 echo "
"; $animal->test();//输出:2