Вы спрашиваете: «Почему Java не поддерживает множественное наследование реализации?»
Это обсуждается в учебниках Java, Multiple Inheritance of State, Implementation, and Type, но я хотел привести конкретный пример проблем множественного наследования реализации (а также в конце концов нового решения по языковым функциям).
Представьте себе два интерфейса (в нашей предлагаемой версии Java, которая позволяет телам методов интерфейса), которые определяют метод с тем же именем.
public interface FaceOne {
public void method() {
System.out.println("FaceOne Version");
}
}
public interface FaceTwo {
public void method() {
System.out.println("FaceTwo Version");
}
}
И класс реализует оба интерфейса, но не переопределяет метод.
public class Inheriter implements FaceOne, FaceTwo {
}
Когда я звоню Inheriter.method()
, который работает так как класс наследует метод от своих предков, возникает проблема: делает вывод на печать «FaceOne Version» или «FaceTwo версия»?
Кроме того, если класс должен был переопределить метод, но захотел также вызвать версию своего предка, используя super
, компилятору снова возникнет проблема выбора между версией метода.
Именно поэтому Java не поддерживает множественное наследование реализации.
Как в стороне, я думаю, что это элегантный способ осуществить это на язык будет выглядеть следующим образом:
Продолжить, чтобы заставить реализующие классы переопределить методы их предок интерфейса. Это решает первую проблему непереопределенного метода.
Затем используйте аналогичную запись, как that of accessing an enclosing instance for an inner class, для доступа к определенному интерфейсу предка с super
. Класс Inheriter затем есть несколько вариантов:
Не называйте super.method()
, а только использовать вновь определенную реализацию.
Используйте FaceOne.super.method()
, чтобы сделать унаследованный результат реализации по умолчанию «FaceOne Version».
Используйте FaceTwo.super.method()
, чтобы сделать унаследованный результат реализации по умолчанию «FaceTwo Version».
Используйте комбинацию выше:
Одна реализация может быть:
@Override
public void method() {
FaceOne.super.method();
FaceTwo.super.method();
System.out.println("Inheriter Version");
}
Выведение:
FaceOne Версия
FaceTwo Версия
Inheriter Версия
Edit: По this question это, по-видимому, как именно по умолчанию реализации структурированы в Java 8.
, потому что в противном случае вы бы получили беспорядок регулярной (C++, как) множественным наследование, которое обычно является избыточным комплексообразованием. – amit
Мне было предложено это на собеседовании, не могли бы вы рассказать об этом –
Интерфейсы - это * не * "множественное наследование". Множественное наследование уродливое, интерфейсы прекрасны;) И интерфейсы не * переопределены *, они «реализованы». Чтобы понять Java-интерфейсы, вам нужно понять «полиморфизм OO». Интерфейсы Java - это КОНТРАКТ, который должен выполняться классом реализации HONOR. Интерфейсы Java - это «спецификация»; класс реализации обеспечивает фактическое «поведение». – paulsm4