Wenn ein Typ zwei Schnittstellen implementiert und jeweils interface
eine Methode mit identischer Signatur definiert, gibt es tatsächlich nur eine Methode, und sie sind nicht unterscheidbar. Wenn die beiden Methoden beispielsweise widersprüchliche Rückgabetypen haben, liegt ein Kompilierungsfehler vor. Dies ist die allgemeine Regel für Vererbung, Überschreiben, Ausblenden und Deklarieren von interface
Methoden und gilt auch für mögliche Konflikte nicht nur zwischen zwei geerbten Methoden, sondern auch für eine interface
und eine Supermethode class
oder auch nur für Konflikte aufgrund der Typlöschung von Generika.
Kompatibilitätsbeispiel
Hier ist ein Beispiel, in dem Sie eine haben interface Gift
, die eine present()
Methode hat (wie in, Geschenke präsentieren), und auch eine interface Guest
, die auch eine present()
Methode hat (wie in, der Gast ist anwesend und nicht abwesend).
Presentable johnny
ist sowohl a Gift
als auch 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!!!"
}
}
Das obige Snippet wird kompiliert und ausgeführt.
Beachten Sie, dass nur eine @Override
erforderlich ist !!! . Dies liegt daran, dass Gift.present()
und Guest.present()
" @Override
äquivalent" sind ( JLS 8.4.2 ).
Es gibt also johnny
nur eine Implementierung von present()
, und es spielt keine Rolle, wie Sie behandeln johnny
, ob als Gift
oder als Guest
, es gibt nur eine Methode, die aufgerufen werden kann.
Beispiel für Inkompatibilität
Hier ist ein Beispiel, in dem die beiden geerbten Methoden NICHT @Override
-äquivalent sind:
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"
}
Dies bekräftigt weiter, dass das Erben von Mitgliedern von a interface
die allgemeine Regel der Mitgliedererklärungen befolgen muss. Hier haben wir Gift
und Guest
definieren present()
mit inkompatiblen Rückgabetypen: eine void
der anderen boolean
. Aus dem gleichen Grund, aus dem Sie ein void present()
und ein boolean present()
in einem Typ nicht können, führt dieses Beispiel zu einem Kompilierungsfehler.
Zusammenfassung
Sie können Methoden erben, die @Override
-äquivalent sind, vorbehaltlich der üblichen Anforderungen zum Überschreiben und Ausblenden von Methoden. Da sie SIND @Override
-Äquivalent, effektiv ist es nur eine Methode zu implementieren, und somit gibt es nichts zu unterscheiden / Auswahl.
Der Compiler muss nicht identifizieren, welche Methode für welche Schnittstelle @Override
geeignet ist , da sie, sobald festgestellt wurde, dass sie gleichwertig sind, dieselbe Methode sind.
Das Beheben potenzieller Inkompatibilitäten mag eine schwierige Aufgabe sein, aber das ist insgesamt ein anderes Problem.
Verweise