Якщо тип реалізує два інтерфейси, і кожен interfaceвизначає метод, що має ідентичну підпис, то по суті існує лише один метод, і вони не відрізняються. Якщо, скажімо, два способи мають суперечливі типи повернення, то це буде помилка компіляції. Це загальне правило успадкування, переосмислення методу, приховування та декларації, і стосується також можливих конфліктів не лише між двома успадкованими interfaceметодами, але також interfaceі супер classметодом, або навіть просто конфліктами через стирання типу дженериків.
Приклад сумісності
Ось приклад, коли у вас є метод interface Gift, який має present()метод (як у поданні подарунків), а також метод interface Guest, який також має present()метод (як, наприклад, гість присутній і не відсутній).
Presentable johnnyє і a, 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!!!"
}
}
Вищенаведений фрагмент збирається та запускається.
Зауважте, що є лише один @Override необхідний !!! . Це тому, що Gift.present()і Guest.present()є " @Override-еквівалентними" ( JLS 8.4.2 ).
Таким чином, johnny має тільки одну реалізацію з present(), і це не має значення , як ви ставитеся johnny, то чи як Giftабо як Guest, є тільки один метод для виклику.
Приклад несумісності
Ось приклад, коли два успадкованих методу НЕ є @Overrideеквівалентними:
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"
}
Далі ще раз підтверджується, що успадковування членів від обов'язку interfaceповинно підкорятися загальному правилу декларацій членів. Ось ми Giftі Guestвизначимо present()з несумісними типами повернення: один voidза одним boolean. З тієї ж причини, що ви не можете використовувати один void present()і boolean present()один тип, цей приклад призводить до помилки компіляції.
Підсумок
Ви можете успадковувати методи, які є @Overrideеквівалентними, за умови звичних вимог методу, що перекриває та приховує. Оскільки вони НЕ @Override еквівалентні, фактично існує лише один метод реалізації, і, отже, немає чого відрізняти / вибирати.
Компілятору не потрібно визначати, який метод є для якого інтерфейсу, тому що коли вони визначаються як @Override-еквівалентні, вони є тим самим методом.
Вирішення потенційної несумісності може бути складним завданням, але це зовсім інше питання.
Список літератури