通俗来讲, Trait类不是类,无法直接使用new关键词来创建对象。
传统的PHP类是单一继承模式,即每个类只能继承一个父类。
Trait类的出现让PHP类可以继承多个“父类”。
一、如何使用:
定义一个Class :
Class cDemo { public function cfun() { return __METHOD__; } }
定义两个Trait类:
Trait tDemo1 { public function fun1() { return __METHOD__; } } Trait tDemo2 { public function fun2() { return __METHOD__; } }
接下来使用一个class 来继承上面的自定义的类
class myClass extends cDemo { // 引用Trait类 use tDemo1, tDemo2; } // 实例化类 $obj = new myClass(); // 调用父类方法 echo $obj->cfun(); // cDemo::cfun 这个是父类cDemo中定义的方法 // 调用Trail中的方法 echo $obj->fun1(); // tDemo1::fun1 echo $obj->fun2(); // tDemo2::fun2
二、注意事项
1. 优先级关系 本类中的方法 > Trait中的方法 > 父类中的方法
2. 当一个类继承了多个Trail,且多个Trait中都包含相同的方法时,调用此方法则会报错;解决方案:
使用 insteadof 关键字和 as 关键字 (insteadof 是进行替代,而as是给它取别名)
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 $cat->drive(); //This is trait1 drive $dog = new dog(); $dog->eat(); //This is trait1 eat $dog->drive(); //This is trait1 drive $dog->eaten(); //This is trait2 eat $dog->driven(); //This is trait2 drive
如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。
为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。
以上方式仅允许排除掉其它方法,as 操作符可以 为某个方法引入别名。 注意,as 操作符不会对方法进行重命名,也不会影响其方法。
as 还可以修改方法的访问控制
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();//报错,已经改成了私有的访问控制
Trait也可以互相组合,还可以使用抽象方法,静态属性,静态方法等,实例如下
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 $animal->eat(); //This is Cat eat $animal->drive(); //This is Dog drive $animal::say(); //This is Dog say $animal->test(); //1 $animal->test(); //2
参考:
本文为崔凯原创文章,转载无需和我联系,但请注明来自冷暖自知一抹茶ckhttp://www.cksite.cn