转自: https://www.jianshu.com/p/fc053b2d7fd1
php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性(听说这个Trait和Go语言有点类似,具体没学过Go语言)
用法:通过在类中使用use 关键字,声明要组合的Trait名称,具体的Trait的声明使用Trait关键词,Trait不能实例化
如下代码实例:
<?phptrait 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();echo "<br/>";$cat->eat();echo "<br/>";$cat->bark();?>
将会如下输出
Paste_Image.png
再测试Trait、基类和本类对同名属性或方法的处理,如下代码
<?phptrait 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();echo "<br/>";$cat->eat();?>
如下显示
Paste_Image.png
所以:Trait中的方法或属性会覆盖 基类中的同名的方法或属性,而本类会覆盖Trait中同名的属性或方法
一个类可以组合多个Trait,通过逗号相隔,如下
use trait1,trait2
当不同的trait中,却有着同名的方法或属性,会产生冲突,可以使用insteadof或 as进行解决,insteadof 是进行替代,而as是给它取别名
如下实例:
<?phptrait 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();echo "<br/>";$cat->drive();echo "<br/>";echo "<br/>";echo "<br/>";$dog = new dog();$dog->eat();echo "<br/>";$dog->drive();echo "<br/>";$dog->eaten();echo "<br/>";$dog->driven();?>
输出如下
Paste_Image.png
as 还可以修改方法的访问控制
<?phptrait 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也可以互相组合,还可以使用抽象方法,静态属性,静态方法等,实例如下
<?phptrait 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();?>
输出如下
作者:依恋灬
链接:https://www.jianshu.com/p/fc053b2d7fd1
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
PHP7之Trait详解
原文地址:https://www.cnblogs.com/taozi32/p/9231413.html