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

相關文章
相關標籤/搜索