在閱讀laravel文件的時候看到一個類 是以 Trait宣告的。平時在工作中從來沒有用過,於是就去看了下官方文件。原來這個類早在php5.4.0
就有了。可惜在專案中從來沒有用過。
Trait看上去既像類又像介面,其實都不是,Trait可以看做類的部分實現,可以混入一個或多個現有的PHP類中,其作用有兩個:表明類可以做什麼;提供模組化實現。Trait是一種程式碼複用技術,為PHP的單繼承限制提供了一套靈活的程式碼複用機制。
為什麼使用Trait
PHP語言使用一種典型的單繼承模型,在這種模型中,我們先編寫一個通用的根類,實現基本的功能,然後擴充套件這個根類,建立更具體的子類,直接從父類繼承實現。這叫做繼承層次結構,很多程式語言都使用這個模式。大多數時候這種典型的繼承模型能夠良好運作,但是如果想讓兩個無關的PHP類具有類似的行為,應該怎麼做呢?
Trait就是為了解決這種問題而誕生的。Trait能夠把模組化的實現方式注入多個無關的類中,從而提高程式碼複用。
下面看幾個簡單的例子
簡單使用
trait Member
{
public function info()
{
echo `this is trait`;
}
}
class ShowMember
{
use Member;
}
$Member = new ShowMember();
$Member->info();
以上程式碼會輸出this is trait
,從這裡可以看出Trait的使用方法很簡單,即使用use關鍵字。可能你已經注意到,名稱空間和Trait使用的都是use關鍵字,不同之處在於匯入位置,名稱空間在類的定義體外匯入,而Trait在類的定義體內匯入。
優先順序
當一個類繼承的基類,跟使用的Trait有相同的函式名稱時,應該是哪一個優先呢,下面我們來看一看。
trait Member
{
public function info()
{
echo `this is trait`;
}
}
class BaseMember
{
public function info()
{
echo `this is base`;
}
}
class ShowMember extends BaseMember
{
use Member;
}
$Member = new ShowMember();
$Member->info();
以上程式碼會輸出this is trait
。可以看出,當繼承的基類與Trait有相同的函式時,Trait的優先順序是比基類要高的。下面把Trait的程式碼做一個修改
trait Member
{
public function info()
{
parent::info();
echo `this is trait`;
}
}
class BaseMember
{
public function info()
{
echo `this is base`;
}
}
class ShowMember extends BaseMember
{
use Member;
}
$Member = new ShowMember();
$Member->info();
以上程式碼會輸出this is basethis is trait
。同樣可以看出Trait的優先順序比基類要高,並且可以再Trait中繼承基類的函式。下面再把程式碼做一個修改。
trait Member
{
public function info()
{
echo `this is trait`;
}
}
class BaseMember
{
public function info()
{
echo `this is base`;
}
}
class ShowMember extends BaseMember
{
use Member;
public function info()
{
echo `this is show`;
}
}
$Member = new ShowMember();
$Member->info();
以上程式碼會輸出this is show
。可以看出優先順序的順序為,當前類的優先順序》Trait》基類。