2013-07-05 9 views
11

Questo codice funziona perfettamente. Il metodo test() funziona per entrambe le interfacce. Cosa sta succedendo esattamente sotto il cofano? E come questa caratteristica è utile nello scenario pratico?Implementazione di più interfacce con lo stesso metodo

interface A 
{ 
    void test(); 
} 

interface B 
{ 
    void test(); 
} 

class C implements A, B 
{ 

    public void test() 
    { 
     System.out.println("abc"); 
    } 
} 

    A a = new C(); 
    a.test(); 
    B b = new C(); 
    b.test(); 
+0

possibile duplicato di [classe astratta Java implementa un'interfaccia, entrambi hanno lo stesso metodo] (http://stackoverflow.com/questions/15202185/java-abstract-class-implements-an-interface-both-have-the -same-method) –

+0

Per favore, anche se il duplicato riguarda le classi e le interfacce astratte, è fondamentalmente lo stesso con due interfacce. –

+0

possibile duplicato di [Implemeting 2 interfacce in una classe con lo stesso metodo. Quale metodo di interfaccia è sovrascritto?] (Http://stackoverflow.com/questions/2801878/implemeting-2-interfaces-in-a-class-with-same -method-which-interface-method-is-o) – adatapost

risposta

12

Perché è un'interfaccia non c'è niente di male. Stai fondamentalmente utilizzando un modello per la tua classe C implementando A e B. Sia A e B dire che C dovrebbe implementare un metodo chiamato test()

La classe C implementa tale metodo, in modo che le interfacce hanno fatto il loro lavoro.

E 'fondamentalmente la classe C detto: "Oh, hey, ho bisogno di implementare test() a causa di interfaccia A" e di implementarlo. Quindi la tua classe C dice "Oh hey, ho bisogno di implementare test() di nuovo a causa dell'interfaccia B" e vede che esiste già un metodo chiamato test() implementato in modo che sia soddisfatto.

si possono anche trovare maggiori informazioni qui: JLS §8.4.8.4

1

Non per quanto riguarda la sintassi è interessato, ma se il intent di uno dei methods non è rispettato, il suo contratto è rotto e il codice può essere considerato come rotto.

Usando la tua analogia, se avessi promesso a Michael di indossare una camicia blu invece di una camicia rossa, e non potrei indossare due magliette, allora dovrò infrangere almeno una promessa.

Lo stesso può valere per i metodi: se mantenere un contratto significherebbe rompere l'altro, in effetti è una cattiva idea per implement entrambi interfaces.

Edit: Contratto rotto, Secondo Class C signature Dovrebbe implementare due metodi, ma alla fine la sua esecuzione solo uno method e omettendo altro.

Reference

+0

Puoi spiegare dove e come un ** contratto è rotto ** qui? – NINCOMPOOP

+0

Contratto rotto, Come per la firma di classe C Dovrebbe implementare due metodi, ma alla fine implementare solo un metodo e omettere un altro. –

+3

* Dovrebbe implementare due metodi * ??? Dovrebbe implementare un metodo dichiarato come 'void test()', dov'è il secondo? – NINCOMPOOP

6

JLS §8.4.8.4 dice,

Metodi Ereditare con le firme Override-Equivalente

E 'possibile per una classe di ereditare più metodi con firme override-equivalenti (§8.4.2)
...
Là potrebbero essere diversi percorsi con cui la stessa dichiarazione di metodo potrebbe essere ereditata da un'interfaccia. Questo fatto non crea difficoltà e mai, di per sé, si traduce in un errore in fase di compilazione.

sembra la logica era che se una classe ha dichiarazioni multiple con lo stesso nome e la firma, dal momento che la classe può averli ereditati attraverso molteplici percorsi-applicazione un'interfaccia e anche sottoclassi una classe che implementa l'interfaccia, per esempio: nessun danno è fatto.

+0

Cosa succede se il tipo di ritorno del metodo è diverso nelle due interfacce? –

+0

@premktiw Errore di compilazione. La frase chiave in JLS è * firme equivalenti a override *. Non è legale cambiare il tipo di reso in un override. – andrewdotn

2
interface A 
{ 
void test(); 
} 

interface B 
{ 
void test(); 
} 
class C implements A, B { 

    public void test() 
    { 
     System.out.println("common to all"); 
    } 
    public A choose(A a){ 
     return new A(){ 
      public void test() { 
       System.out.println("test of A"); 
      } 
     }; 
    } 
    public B choose(B b){ 
     return new B(){ 
      public void test() { 
      System.out.println("test of B"); 
      } 
     }; 
    } 
} 
class Demo { 
    public static void main(String[] args) { 
    C c =new C(); 

    A a = new C(); 
    B b = new B(); 

    a = c.choose(a); 
    b = c.choose(b); 

    a.test(); 
    b.test(); 
    } 
} 
+4

Il codice senza spiegazione non è una risposta – BrDaHa

5

Supponiamo di avere due interfacce ...

public interface StockBroker{ 
     //Give our client some investment strategies. 
     public String adviseClient(Client c); 
} 

public interface Doctor{ 
    //Examine our client and give them some medical advice 
     public String adviseClient(Client c); 
} 

E una classe che implementa entrambe le interfacce ....

public class JackOfAllTrades implements StockBroker, Doctor{ 
    public String adviseClient(Client c){ 
    } 
} 

Mentre può essere sintatticamente corretto per implementare entrambe le interfacce con un metodo, potresti non ottenere il comportamento desiderato. Ad esempio, un agente di borsa e un medico di solito danno ai loro clienti consigli molto diversi.

Qualcuno che utilizza un oggetto che implementa l'interfaccia Doctor si aspetta che il metodo adviseClient() dia un parere medico. Ma qualcuno che utilizza un oggetto che implementa l'interfaccia StockBroker si aspetta che il metodo adviseClient() distribuisca strategie di investimento.

In questo caso, l'oggetto JackOfAllTrades non sa che tipo di consiglio da dare fuori perché il metodo non ha parametri adviseClient() dicono che quale interfaccia si suppone essere di esecuzione quando adviseClient() si chiama.

Questa è una limitazione in Java perché la persona che progetta l'interfaccia Doctor potrebbe non avere modo di sapere che qualcun altro avrebbe progettato un'interfaccia StockBroker con la stessa firma del metodo.

Per chiunque crei interfacce, è probabilmente buona norma rendere i nomi dei metodi univoci abbastanza che le collisioni di nomi sono rare.

Problemi correlati