什麼是特質

PHP 只允許單繼承。換句話說,一個類只能改變另一個類。但是如果你需要包含一些不屬於父類的東西呢?在 PHP 5.4 之前,你必須具有創造性,但在 5.4 中引入了特徵。特徵允許你基本上將一部分類複製並貼上到主類中

trait Talk {
    /** @var string */
    public $phrase = 'Well Wilbur...';
    public function speak() {
         echo $this->phrase;
    }
}

class MrEd extends Horse {
    use Talk;
    public function __construct() {
         $this->speak();
    }

    public function setPhrase($phrase) {
         $this->phrase = $phrase;
    }
}

所以這裡我們有 MrEd,它已經擴充套件了 Horse。但不是所有的馬匹都是如此,所以我們有一個特點。讓我們注意一下這是做什麼的

首先,我們定義我們的特質。我們可以將它與自動載入和名稱空間一起使用(另請參閱在名稱空間中引用類或函式 )。然後我們將它包含在我們的 MrEd 類中,並使用關鍵字 use

你會注意到 MrEd 需要使用 Talk 函式和變數而不定義它們。還記得我們關於複製和貼上的內容嗎?這些函式和變數現在都在類中定義,就好像這個類定義了它們一樣。

特徵與抽象類最密切相關,因為你可以定義變數和函式。你也無法直接例項化 Trait(即 new Trait())。Traits 不能強制類隱式定義類似 Abstract 類或 Interface 的函式。特徵用於顯式定義(因為你可以根據需要使用多個介面,請參閱介面 )。

我什麼時候應該使用特質?

在考慮特質時,你應該做的第一件事就是問自己這個重要的問題

我可以通過重構程式碼來避免使用 Trait 嗎?

通常情況下,答案是肯定的。特徵是由單一繼承引起的邊緣情況。濫用或過度使用特徵的誘惑可能很高。但請考慮 Trait 為你的程式碼引入了另一個來源,這意味著還有另一層複雜性。在這裡的例子中,我們只處理 3 個類。但 Traits 意味著你現在可以處理的遠不止這些。對於每個特徵,你的類變得更難以處理,因為你現在必須引用每個特徵以找出它定義的內容(並且可能發生碰撞的位置,請參閱衝突解決 )。理想情況下,你應該儘可能少地保留程式碼中的 Traits。