Если тип реализует два интерфейса, и каждый из них 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
-эквивалентные, они становятся одним и тем же методом.
Устранение потенциальных несовместимостей может быть сложной задачей, но это совсем другая проблема.
Ссылки