Если тип реализует два интерфейса, и каждый из них interfaceопределяет метод с одинаковой сигнатурой, то в действительности существует только один метод, и они не различимы. Если, скажем, два метода имеют конфликтующие типы возврата, то это будет ошибка компиляции. Это общее правило наследования, переопределения методов, скрытия и объявлений, а также применяется к возможным конфликтам не только между 2 унаследованными interfaceметодами, но также interfaceи к супер- classметоду, либо даже просто к конфликтам из-за стирания обобщенных типов.
Пример совместимости
Вот пример, где у вас есть метод interface Gift, у которого есть present()метод (например, для представления подарков), а также метод interface Guest, у которого также есть present()метод (например, гость присутствует, а не отсутствует).
Presentable johnnyэто Giftи а 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()a и a boolean present()в одном типе, этот пример приводит к ошибке компиляции.
Резюме
Вы можете наследовать методы, которые @Overrideэквивалентны, при условии соблюдения обычных требований переопределения и сокрытия методов. Поскольку они ARE @Override -эквивалентны, эффективно существует только один способ реализации, и , таким образом , нет ничего , чтобы отличить / выбор.
Компилятору не нужно определять, какой метод предназначен для какого интерфейса, потому что, как только они определены как @Override-эквивалентные, они становятся одним и тем же методом.
Устранение потенциальных несовместимостей может быть сложной задачей, но это совсем другая проблема.
Ссылки