官方解釋
? ? ? ?自 PHP 5.4.0 起,PHP 實(shí)現(xiàn)了一種代碼復(fù)用的方法,稱為 trait。
? ? ? ?Trait是為類似 PHP 的單繼承語言而準(zhǔn)備的一種代碼復(fù)用機(jī)制(減少代碼重復(fù),增加代碼復(fù)用性)。
? ? ? ?Trait為了減少單繼承語言的限制,使開發(fā)人員能夠自由地在不同層次結(jié)構(gòu)內(nèi)獨(dú)立的類中復(fù)用 method。
? ? ? ?Trait 和 Class 組合的語義定義了一種減少復(fù)雜性的方式,避免傳統(tǒng)多繼承和 Mixin 類相關(guān)典型問題。
? ? ? ?Trait 和 Class 相似,但僅僅旨在用細(xì)粒度和一致的方式來組合功能。 無法通過 trait 自身來實(shí)例化。
優(yōu)先級(jí)
? ? ? ?從基類繼承的成員會(huì)被 trait 插入的成員所覆蓋。優(yōu)先順序是來自當(dāng)前類的成員覆蓋了 trait 的方法,而 trait 則覆蓋了被繼承的方法。
自身方法 > trait方法 > 繼承的方法
調(diào)用
聲明一個(gè)trait
在類中使用use引入trait
使用多個(gè)trait,用逗號(hào),隔開
沖突
? ? ? ?不同的trait,有同名的方法或?qū)傩裕谕瑫r(shí)引入是會(huì)產(chǎn)生沖突。可以使用insteadof或as來解決。insteadof是替代,as是取別名,as還可以用來修改方法的訪問控制。
其他
? ? ? ?trait可以互相組合,一個(gè)trait中可以引入其他trait(也是使用use)。trait可以使用抽象方法,靜態(tài)方法,靜態(tài)屬性等
代碼如下
<?php
trait Hello{
public function sayHello(){
echo "trait Hello: Hello ";
}
}
trait World{
public function sayHello(){
echo "trait World : Hello ";
}
public function sayWorld(){
echo "world";
}
abstract public function getName();
public static function eat(){
echo "\neat: eat lunch\n";
}
}
trait Access{
protected function accessControll(){
echo "access controll\n";
}
}
class Test{
use Hello, World, Access{
Hello::sayHello insteadof World;
World::sayHello as say;
Access::accessControll as public;
}
public function sentenseEnd(){
echo "!\n";
}
public function getName(){
echo "getName\n";
}
}
$obj = new Test();
$obj->sayHello();
$obj->sayWorld();
$obj->sentenseEnd();
$obj->say();
Test::eat();
$obj->getName();
Test::accessControll();
echo "\n";
Hello::sayHello();//直接調(diào)用
輸出結(jié)果:
trait Hello: Hello world!
trait World : Hello
eat: eat lunch
getName
access controll
trait Hello: Hello