通俗来讲, 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