2013-08-27 76 views
5

在PHP 5.4.9中,以下示例觸發致命錯誤「B具有來自特徵的碰撞構造函數定義」特徵的構造函數定義如何碰撞?

trait T { 
    public function __construct() { 
     echo __CLASS__ . ": constructor called.\n"; 
    } 
} 

class A { 
    use T; 
} 

class B extends A { 
    use T; 
} 

有沒有問題,在特徵包含了與構造不同的方法,並在構造函數實際上是複製到類(不使用特徵,「語言輔助拷貝&粘貼」功能),沒有問題。

這裏的構造函數有什麼特別之處?不應該PHP能夠找出其中一個覆蓋另一個?我無法找到有關此限制in the manual的任何內容。

This related question提到了一種解決問題的方法(通過對特徵方法使用別名),但不是首先引起它的原因。

回答

3

嘗試用下面的代碼會發生什麼:

class A { 
    use T; 
    use T; 
} 

,因爲這是你有效地從A再次延伸,然後用T代表B.

寫道如果您需要使用特質噸基類和子類,只能在基類中使用它。

如果您僅在子類中需要它,請僅在葉子類中使用它。

+0

在這種情況下,我收到了一條不同的錯誤消息:*「特徵方法__construct尚未應用,因爲在A上存在與其他特徵方法的衝突」*。另外,如果導入的方法是構造函數,則沒有區別。該問題中的示例可以很好地與其他方法一起工作,只有構造函數的行爲不同。 – Zilk

+0

@hakre但不解釋,爲什麼不同的方法似乎工作得很好。可以? – SteAp

+0

@Zilk:該錯誤命名不同,因爲* extends *步驟缺失,但這兩個錯誤都告訴您有關碰撞。對於其他*方法,請嘗試其他*魔術方法。我可以想象那些人會有一些不同,因爲你不能混淆他們。他們依賴於他們的名字不能改變,所以沒有別名,所以沒有衝突的資源,所以只是一個碰撞。 – hakre