2011-03-31 13 views
5

Questo non funziona:Non può implementare due interfacce che hanno lo stesso nome del metodo

interface TestInterface 
{ 
    public function testMethod(); 
} 

interface TestInterface2 
{ 
    public function testMethod(); 
} 

class TestClass implements TestInterface, TestInterface2 
{ 

} 

mi dà l'errore:

Fatal error: Can't inherit abstract function TestInterface2::testMethod() (previously declared abstract in TestInterface).

E 'corretto? Perché questo non è permesso? Non ha senso per me.

Ciò accade anche con funzioni astratte, ad esempio se si implementa un'interfaccia e successivamente si eredita da una classe che ha una funzione astratta con lo stesso nome.

risposta

8

Non ha senso implementare due interfacce contenenti metodi con le stesse firme.

Il compilatore non può sapere se i metodi hanno effettivamente lo stesso scopo - in caso contrario, ciò significherebbe che almeno una delle interfacce non può essere implementata dalla classe in.

Esempio:

interface IProgram { function execute($what); /* executes the given program */ } 
interface ISQLQuery { function execute($what); /* executes the given sql query */ } 

class PureAwesomeness implements IProgram, ISQLQuery { 
    public function execute($what) { /* execute something.. but what?! */ } 
} 

Quindi, come vedete, è impossibile implementare il metodo per entrambe le interfacce - e sarebbe anche essere impossibile chiamare il metodo che in realtà implementa il metodo da una determinata interfaccia.

+5

Ma l'intero punto delle interfacce è che non hanno implementazione. Cosa fare se si desidera rendere la classe in grado di essere passata a una funzione che specifica un'interfaccia per un parametro e un'altra che specifica un'altra interfaccia, ma entrambi hanno un metodo in comune? Un nome di metodo come "getName()" non avrà uno scopo diverso su un'interfaccia diversa. – Gnuffo1

+5

In tal caso dovresti creare una nuova interfaccia, ad es. 'INamed' che contiene solo il metodo' getName() '. – ThiefMaster

+1

Non hanno implementazione, ma hanno semantica, almeno implicitamente. Mentre tu * potresti * implementare un metodo in un'interfaccia per avere un significato completamente diverso nelle diverse classi che lo usano, ciò sarebbe contrario allo spirito delle interfacce. Tuttavia, se si implementano due interfacce diverse, non vi è alcuna garanzia che i loro specificatori sapessero qualcosa l'una dell'altra, e quindi che i metodi con lo stesso nome avessero una semantica simile. Immagino che tu possa fare in modo che ogni interfaccia estenda un'interfaccia comune che contiene il metodo comune. –

-1

Questo non è consentito, perché PHP non può essere sicuro di quale interfaccia abbia il metodo desiderato. Nel tuo caso sono identici, ma immagina se avessero parametri diversi.

È necessario riconsiderare la progettazione dell'applicazione.

7

The PHP manual dice esplicitamente:

Prior to PHP 5.3.9, a class could not implement two interfaces that specified a method with the same name, since it would cause ambiguity. More recent versions of PHP allow this as long as the duplicate methods have the same signature.

+0

Non capisco dove possa essere l'ambiguità, dal momento che non ci sono implementazioni (questo è il punto dell'interfaccia). Posso capire perché non vorreste lo stesso metodo con firme diverse, ma, con la stessa firma, non dovrebbe essere lasciato questo per l'implementazione concreta da affrontare? Non è così che funziona, ad esempio, Java? – Muc

+1

Penso che ci sia un argomento per quello che dici: è una decisione che i progettisti di linguaggio prendono fino a che punto ti proteggono da te stesso. Non esiste un'ambiguità _intrinseca, ma se le interfacce hanno funzioni con la stessa firma, la semantica richiesta dalle funzioni potrebbe corrispondere, oppure potrebbero essere completamente diverse. –

+0

Questo sembra all'indietro. Non dovrebbe essere permesso solo se hanno _differenti_ firme? Se i due metodi hanno firme diverse, chiunque chiami uno dei metodi chiama esplicitamente il metodo specifico che desidera. Anche se i due metodi hanno due obiettivi completamente diversi, va bene perché verrà chiamato il metodo corretto. Tuttavia, se i due metodi hanno la stessa firma e l'obiettivo di ciascun metodo è completamente diverso, non ci sarà modo di avere un singolo metodo che possa servire a entrambi gli scopi, quindi un singolo metodo non ha senso. Qualcuno può fornire qualche contro razionale? –

3
interface BaseInterface 
{ 
    public function testMethod(); 
} 

interface TestInterface extends BaseInterface 
{ 
} 

interface TestInterface2 extends BaseInterface 
{ 
} 

class TestClass implements TestInterface, TestInterface2 
{ 
    public function testMethod() 
    { 
    } 
} 
Problemi correlati