Implementing two interfaces in a class with same method. Which interface method is overridden?
Реализация двух интерфейсов в классе с одним и тем же методом. Какой метод интерфейса переопределен?
Два интерфейса с одинаковыми именами методов и сигнатурами. Но реализованы одним классом, тогда как компилятор определит, какой метод для какого интерфейса?
@Override publicintf() { // from which interface A or B return0; } }
Переведено автоматически
Ответ 1
Если тип реализует два интерфейса, и каждый из них interface определяет метод с идентичной сигнатурой, то фактически существует только один метод, и они не различимы. Если, скажем, два метода имеют конфликтующие возвращаемые типы, то это будет ошибка компиляции. Это общее правило наследования, переопределения, скрытия и объявления методов, которое также применяется к возможным конфликтам не только между двумя унаследованными interface методами, но также interface и супер class методами, или даже просто конфликтам из-за стирания типов обобщенных файлов.
Пример совместимости
Вот пример, где у вас есть interface Gift, у которого есть present() метод (например, вручение подарков), а также interface Guest, у которого также есть present() метод (например, гость присутствует, а не отсутствует).
Presentable johnny является одновременно Gift и a Guest.
Приведенный выше фрагмент компилируется и запускается.
Обратите внимание, что необходим только один@Override!!!. Это потому, что Gift.present() и Guest.present() являются "@Overrideэквивалентными" (JLS 8.4.2).
Таким образом, johnnyимеет только одну реализацию из present(), и не имеет значения, как вы относитесь к johnny, будь то как Gift или как a Guest, есть только один метод для вызова.
Пример несовместимости
Вот пример, в котором два унаследованных метода НЕ @Override эквивалентны:
interfacePresentableextendsGift, Guest { } // DOES NOT COMPILE!!! // "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible; // both define present(), but with unrelated return types" }
Это еще раз подтверждает, что наследование членов от interface должно подчиняться общему правилу объявления членов. Здесь мы имеем Gift и Guest define present() с несовместимыми типами возвращаемых значений: один void другой boolean. По той же причине, по которой вы не можете использовать void present() и a boolean present() в одном типе, этот пример приводит к ошибке компиляции.
Краткие сведения
Вы можете наследовать методы, которые @Overrideэквивалентны, при соблюдении обычных требований переопределения и скрытия методов. Поскольку они являются@Override эквивалентными, фактически существует только один метод для реализации, и, следовательно, различать / выбирать не из чего.
Компилятору не нужно определять, какой метод для какого интерфейса предназначен, потому что, как только они определены как @Override-эквивалентные, это один и тот же метод.
Устранение потенциальных несовместимостей может быть сложной задачей, но это совсем другая проблема.
newDEF().hi(); // prints F as it is closer in the heirarchy than A.
Ответ 3
Что касается компилятора, эти два метода идентичны. Будет одна реализация обоих.
Это не проблема, если два метода фактически идентичны в том смысле, что они должны иметь одинаковую реализацию. Если они различаются по контракту (согласно документации для каждого интерфейса), у вас возникнут проблемы.
Ответ 4
Идентифицировать нечего. Интерфейсы запрещают только имя метода и сигнатуру. Если оба интерфейса имеют метод с точно таким же именем и сигнатурой, реализующий класс может реализовать оба метода интерфейса одним конкретным методом.
Однако, если семантические контракты двух интерфейсных методов противоречат друг другу, вы в значительной степени проиграли; тогда вы не сможете реализовать оба интерфейса в одном классе.