2016-03-28 28 views
7

Ho due tratti di PHP che ogni ereditare dalla stessa 3 ° tratto:evitando collisioni di tratti - use_once?

trait C { 
    public function smallTalk() { 
     echo 'c'; 
    } 
} 

trait A { 
    use C; 
    public function ac() { 
     echo 'a'.smallTalk(); 
    } 
} 

trait B { 
    use C; 
    public function bc() { 
     echo 'b'.smallTalk(); 
    } 
} 

E voglio usarli entrambi in una classe:

class D { 
    use A, B; 
    public function acbc() { 
     echo ac().bc(); 
    } 
} 

ma continuo a ricevere l'errore

Fatal error: Trait method smallTalk has not been applied, because there are collisions with other trait methods on D

Lo so use_once non è una cosa, ma sto cercando la stessa funzionalità che require_once o include_once fornisce, ma per i tratti. Questo esempio è semplificato. Il mio vero C ha molti metodi ed è ereditato da molti più di 2 tratti, quindi non voglio davvero dover ripetere una lunga stringa di insteadof ogni volta che uso più di 1 di questi tratti.

+0

versione corta: No, movimentazione manuale collisioni è il prezzo per l'utilizzo di tratti. – VolkerK

+0

Sospetto che tu stia abusando di tratti. Io uso solo i tratti come ultima risorsa. Questa risposta ha una buona spiegazione sulle alternative (in C++, ma si applicano principalmente a qualsiasi linguaggio OOP) http://stackoverflow.com/questions/406081/why-should-i-avoid-multiple-inheritance-in-c# answer-407928 – Pevara

risposta

0

hai bisogno di leggere: Conflict Resolution

If two Traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.

To resolve naming conflicts between Traits used in the same class, the insteadof operator needs to be used to choose exactly one of the conflicting methods.

Since this only allows one to exclude methods, the as operator can be used to allow the inclusion of one of the conflicting methods under another name.

Esempio:

<?php 
trait A { 
    public function smallTalk() { 
     echo 'a'; 
    } 
    public function bigTalk() { 
     echo 'A'; 
    } 
} 

trait B { 
    public function smallTalk() { 
     echo 'b'; 
    } 
    public function bigTalk() { 
     echo 'B'; 
    } 
} 

class Talker { 
    use A, B { 
     B::smallTalk insteadof A; 
     A::bigTalk insteadof B; 
    } 
} 

class Aliased_Talker { 
    use A, B { 
     B::smallTalk insteadof A; 
     A::bigTalk insteadof B; 
     B::bigTalk as talk; 
    } 
} 
+0

Hai letto la domanda? "La mia vera C ha molti metodi ed è ereditata da molti più di 2 tratti, quindi non voglio davvero dover ripetere una lunga serie di invece ogni volta che uso più di 1 di questi tratti." So che posso fare quello che stai dicendo, ma stavo chiedendo se c'era una soluzione migliore. – wogsland

+1

Non sarà in grado di risolvere il conflitto con altri mezzi. Usa il tratto + esteso. Se vuoi fare tutto "bene" - non provare a fare tutto con l'aiuto del tratto. È possibile creare una classe C. D estesa da C. Senza un esempio reale - difficile dire quale architettura sarà vera. Consiglio di familiarizzare con il SOLIDO. Può aiutare a selezionare l'architettura. –

+0

Venerato perché questa è la risposta corretta, anche se a OP non piace che sia la risposta corretta. – mopsyd