PHP 特性之 trait (一)

舊夢發癲發表於2019-02-16

  在閱讀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》基類。

相關文章