Trait详解

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

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

看实例:code

1.blog

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.get

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也能够互相组合,还能够使用抽象方法,静态属性,静态方法等

来源:it

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

相关文章
相关标签/搜索