由於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