Se un tipo implementa due interfacce e ognuna interfacedefinisce un metodo con firma identica, in effetti esiste un solo metodo e non sono distinguibili. Se, per esempio, i due metodi hanno tipi di ritorno in conflitto, allora si tratterà di un errore di compilazione. Questa è la regola generale dell'ereditarietà, dell'override del metodo, del nascondimento e delle dichiarazioni, e si applica anche a possibili conflitti non solo tra 2 interfacemetodi ereditati , ma anche un interfacee un classmetodo super , o anche solo conflitti dovuti alla cancellazione del tipo di generici.
Esempio di compatibilità
Ecco un esempio in cui hai un interface Gift, che ha un present()metodo (come in, presentare regali), e anche un interface Guest, che ha anche un present()metodo (come in, l'ospite è presente e non assente).
Presentable johnnyè sia a Giftche a Guest.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
Lo snippet sopra riportato viene compilato ed eseguito.
Si noti che ce n'è solo uno @Override necessario !!! . Questo perché Gift.present()e Guest.present()sono " @Overrideequivalenti" ( JLS 8.4.2 ).
Quindi, johnny ha solo un'implementazione di present(), e non importa come tratti johnny, sia come Giftche come Guest, c'è solo un metodo da invocare.
Esempio di incompatibilità
Ecco un esempio in cui i due metodi ereditati NON sono @Overrideequivalenti:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
Ciò ribadisce inoltre che ereditare i membri da una interfacedeve obbedire alla regola generale delle dichiarazioni dei membri. Qui abbiamo Gifte Guestdefiniamo present()con tipi di ritorno incompatibili: uno voidl'altro boolean. Per lo stesso motivo per cui non è possibile un void present()e un boolean present()tipo, questo esempio genera un errore di compilazione.
Sommario
È possibile ereditare metodi @Overrideequivalenti, soggetti ai normali requisiti di sostituzione e occlusione del metodo. Dal momento che SONO @Override equivalenti, in effetti esiste solo un metodo da implementare, e quindi non c'è nulla da distinguere / selezionare.
Il compilatore non deve identificare quale metodo è per quale interfaccia, perché una volta che sono determinati per essere @Overrideequivalenti, sono lo stesso metodo.
Risolvere potenziali incompatibilità può essere un compito complicato, ma questo è un altro problema.
Riferimenti