Jeśli typ implementuje dwa interfejsy, a każdy z nich interface
definiuje metodę o identycznej sygnaturze, to w efekcie istnieje tylko jedna metoda i nie można ich rozróżnić. Jeśli, powiedzmy, dwie metody mają sprzeczne typy zwrotów, oznacza to błąd kompilacji. Jest to ogólna zasada dziedziczenia, zastępowania metod, ukrywania i deklaracji, i ma zastosowanie również do ewentualnych konfliktów nie tylko między 2 odziedziczonymi interface
metodami, ale także metodą interface
super i super class
, a nawet po prostu konfliktów spowodowanych usunięciem typów ogólnych.
Przykład kompatybilności
Oto przykład, w którym masz metodę interface Gift
, która ma present()
metodę (jak w, prezentowanie prezentów), a także interface Guest
, która również ma present()
metodę (jak w, gość jest obecny i nieobecny).
Presentable johnny
jest zarówno Gift
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!!!"
}
}
Powyższy fragment kompiluje się i uruchamia.
Pamiętaj, że jest tylko jedna @Override
konieczna !!! . To dlatego, że Gift.present()
i Guest.present()
są " @Override
-equivalent" ( JLS 8.4.2 ).
Tak więc, johnny
ma tylko jedną implementację o present()
, i to nie ma znaczenia, w jaki sposób leczyć johnny
, czy jako Gift
lub jako Guest
, że jest tylko jeden sposób, aby wywołać.
Przykład niezgodności
Oto przykład, w którym dwie odziedziczone metody NIE są @Override
równoważne:
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"
}
To jeszcze bardziej przypomina, że dziedziczenie członków po konieczności interface
musi być zgodne z ogólną zasadą deklaracji członków. Tutaj mamy Gift
i Guest
definiujemy present()
niekompatybilne typy zwrotów: jeden void
drugi boolean
. Z tego samego powodu, że nie można void present()
oraz boolean present()
w jednym rodzaju, przykład ten powoduje błąd kompilacji.
Podsumowanie
Możesz dziedziczyć metody, które są @Override
ekwiwalentne, z zastrzeżeniem zwykłych wymagań zastępowania i ukrywania metod. Ponieważ SĄ @Override
-equivalent, skutecznie istnieje tylko jeden sposób do wdrożenia, a więc nie ma nic do odróżnienia / wyboru.
Kompilator nie musi określać, która metoda jest przeznaczona dla @Override
danego interfejsu, ponieważ po ustaleniu , że są równoważne, są one tą samą metodą.
Rozwiązanie potencjalnych niezgodności może być trudnym zadaniem, ale to zupełnie inna kwestia.
Bibliografia