一、 trait、继承、实例化三者的区别
对于当前一个类需要用到另一个或多个类的方法的情况,我们一般会想到的方式有继承、直接实例化另外一个或多个类等等的方法,来对比一下这些方法和Trait类的区别:
- 继承:对于继承,可以完美地复用另一个类的一些方法,但是对于需要复用多个类的方法时,PHP是不支持多继承的,而且只能访问public和protected方法
- 直接实例化:我们也可以在当前类中直接实例化要用到的A类与B类,但是这种方法在控制访问范围反面,只允许访问A、B类中public的方法
- Trait:使用Trait类则完全将A、B两个类的方法导入到当前类中,可以视为当前类的一部分,唯一区别是可以存在于当前类同名的方法,此时由优先级顺序来控制
二、 Trait类的优先级控制
- 当前使用类 > Trait类 > 继承的基类
- 当存在同名方法时,会根据优先级覆盖掉同名的类
三、 多个Trait类的冲突控制
在PHP中,如果当前类use了两个Trait类,同时两个trait类都存在一个同名的方法,此时如果没有明确解决冲突将会产生一个致命错误。对于这种情况,PHP官方给出了两个解决方案:
- insteadof关键字:通过该关键字指定方法名冲突时该使用哪个Trait类的方法,即:
如果C类use了A、B两个Trait类,且A、B两个类都存在a、b方法,则在C类use A、B类时使用insteadof声明冲突的解决方法即可:// An highlighted block use A, B { B::a insteadof A; //a方法冲突时使用B类的a方法而不使用A类的a方法 A::b insteadof B; //b方法冲突时使用A类的b方法而不使用B类的b方法 }
- as关键字:通过as关键字将同名方法指定为一个别名,且仅作用于当前类中:
use A, B { B::a as c; //声明B类的a方法为c,作用于该类 A::b as d; //声明A类的b方法为d,作用于该类 }
四、 举个栗子
class Base{
public function sayHello(){
echo "hello ";
}
}
trait SayWorld{
public function sayHello(){
parent::sayHello();
echo "world".PHP_EOL;
}
}
trait SayWorld2{
public function sayHello2(){
echo "PHP".PHP_EOL;
}
}
class MyHelloWorld extends Base{
use SayWorld,SayWorld2;
}
$s = new MyHelloWorld();
$s->sayHello();
$s->sayHello2();
标签:use,trait,使用,Trait,PHP,方法,public
From: https://www.cnblogs.com/program01/p/17384452.html