Trait详解

因为php是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php在5.4后出了Trait这个特性。

php原文:Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。

看实例:

1.

trait Dog{
        public $name = 'Dog';
        public function drive(){
                echo 'This is trait dog drive';
        }
        public function eat(){
                echo 'This is trait dog eat';   
        }
}

class Animal{
        public function drive(){
                echo 'This is class animal drive';
        }
        public function eat(){
                echo 'This is class animal eat';
        }

}

class Cat extends Animal{
        use Dog;
        public function drive(){
                echo 'This is class cat drive';
        }

}

$cat = new Cat();
$cat->drive();
echo "<br>";
$cat->eat();

//输出
//This is class cat drive
//This is trait dog eat
//结论:基类可以重写/调用trait同名的属性或方法;

2.

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 cats{
        use trait1,trait2{
                trait1::eat insteadof trait2;
                trait1::drive insteadof trait2;
        }
}
class dogs{
        use trait1,trait2{
                trait1::eat insteadof trait2;
                trait1::drive insteadof trait2;
                trait2::eat as eaten;
                trait2::drive as driven;
        }
}
$cats = new cats();
$cats->eat();
echo "<br>";
$cats->drive();
echo "<br>";
echo "<br>";
echo "<br>";
$dogs = new dogs();
$dogs->eat();
echo "<br>";
$dogs->drive();
echo "<br>";
$dogs->eaten();
echo "<br>";
$dogs->driven();

//输出
//This is trait1 eat
//This is trait1 drive


//This is trait1 eat
//This is trait1 drive
//This is trait2 eat
//This is trait2 drive
//结论:多trait可以使用,间隔;当不同的trait调用时,有着相同的属性或方法,会产生冲突,可以使用insteadof(进行替代),或者as(对其取别名)

3.

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();//报错,已经改成了私有的访问控制

//结论:as可以修改方法的访问控制

4.

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();
echo "<br/>";
$animal->eat();
echo "<br/>";
$animal->drive();
echo "<br/>";
$animal::say();
echo "<br/>";
$animal->test();
echo "<br/>";
$animal->test();
echo "<br/>";
$animal->test();

//输出
//This is animal name
//This is Cat eat
//This is Dog drive
//This is Dog say
//1
//2
//3
//结论:Trait也可以互相组合,还可以使用抽象方法,静态属性,静态方法等

来源:

https://www.jianshu.com/p/fc053b2d7fd1

猜你喜欢

转载自www.cnblogs.com/two-bees/p/11353960.html
今日推荐