2013-08-27 14 views
5

In PHP 5.4.9, il seguente esempio attiva l'errore irreversibile "B ha definizioni di costruttore in conflitto che provengono dai tratti".Come si possono scontrare le definizioni dei costruttori dai tratti?

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

class A { 
    use T; 
} 

class B extends A { 
    use T; 
} 

Non c'è nessun problema quando il tratto contiene un metodo diverso da quello del costruttore, e nessun problema quando il costruttore è in realtà copiato nelle classi (senza l'utilizzo di tratti, la funzione "copia lingua assistita & incolla").

Cosa c'è di così speciale nel costruttore qui? Il PHP non dovrebbe essere in grado di capire che uno di essi ha la precedenza sull'altro? Non ho trovato nulla su questa limitazione in the manual.

This related question menziona un modo per aggirare il problema (utilizzando alias per i metodi di tratto), ma non ciò che lo sta causando in primo luogo.

risposta

3

Prova cosa succede con il seguente codice:

class A { 
    use T; 
    use T; 
} 

perché questo è quello che hai scritto in modo efficace estendendo da A e quindi utilizzando T nuovo per B.

Se è necessario utilizzare tratto T a base e sottoclassi, usalo solo nella classe base.

Se ne avete bisogno solo in sottoclassi, usatelo solo nelle sottoclassi foglia.

+0

In questo caso viene visualizzato un messaggio di errore diverso: * "Il metodo dei tratti __costruttura non è stato applicato, perché ci sono collisioni con altri metodi di tratto su A" *. Inoltre, non fa differenza se il metodo importato è un costruttore o meno. L'esempio nella domanda funziona bene con altri metodi, solo il costruttore si comporta diversamente. – Zilk

+0

@hakre Ma non spiega, perché un metodo diverso sembra funzionare bene. Lo fa? – SteAp

+0

@Zilk: l'errore viene chiamato in modo diverso perché manca il passaggio * extends *, ma entrambi gli errori indicano la collisione. Per * altri * metodi, prova anche con altri metodi * magic *. Posso immaginare che ci sarà qualche differenza per quelli perché non puoi farli alias. Sono dipendenti dal loro nome che non può cambiare, quindi nessun aliasing, quindi nessun conflitto in conflitto, quindi solo una collisione. – hakre

Problemi correlati