Когда класс наследует две переменные от родительских интерфейсов, Java настаивает на том, чтобы любое использование рассматриваемого имени переменной было полным. Это решает проблему. См. раздел спецификации языка Java 8.3 :
Класс может наследовать более одного поля с одним и тем же именем. Такая ситуация сама по себе не вызывает ошибку во время компиляции. Однако любая попытка в теле класса ссылаться на любое такое поле по его простому имени приведет к ошибке времени компиляции, потому что такая ссылка неоднозначна.
Аналогичное утверждение применяется в отношении интерфейсов ( JLS §9.3 ).
Пример кода в ответ Оскара Лопеса превосходен. Вот еще один пример:
class Base {
int x = 10;
}
interface Interface {
int x = 20;
}
class SingleInheritance implements Interface {
int y = 2 * x; // ok
}
class MultipleInheritance extends Base implements Interface {
int y = 2 * x; // compile-time error
int z = 2 * Interface.x; // ok
}
void aMethod(MultipleInheritance arg) {
System.out.println("arg.x = " + arg.x); // compile-time error
System.out.println("x = " + Interface.x); // ok
}
Редактировать
Java 8 представляет ограниченную форму множественного наследования для методов, потому что интерфейсы теперь могут объявлять методы по умолчанию , которые могут наследовать подынтерфейсы и реализующие классы. Поскольку класс может реализовывать несколько интерфейсов, это может привести к неоднозначности, поскольку различные методы по умолчанию с одной и той же сигнатурой могут быть унаследованы от нескольких интерфейсов. 1 Java имеет дело с этим, используя схему приоритетов, чтобы указать, какой метод по умолчанию фактически наследуется. , Это требует явного переопределения унаследованных методов по умолчанию, когда схема приоритета не может привести к единственному победителю.
Обратите внимание, что ни в коем случае Java не имеет проблемы Diamond, которая является очень специфическим подклассом проблем, которые могут иметь множественное наследование. 2 Часть "Diamond" относится к форме наследования класса диаграмма, которая требуется для того, чтобы иметь проблему. В C ++ проблема Diamond может возникнуть, если класс A наследует от двух классов B и C, каждый из которых наследует от общего базового класса D. В этом случае любые открытые члены D в конечном итоге появляются дважды в A - один раз наследуются через B и один раз через C. Кроме того, всякий раз, когда экземпляр A создается или уничтожается, конструктор или деструктор для D в конечном итоге вызывается дважды (часто с катастрофическими последствиями, отсюда и часть «смерти» имени). C ++ решает эти проблемы, предоставляя виртуальное наследование . (Подробнее см. Обсуждение здесь .)
1 Обратите внимание на использование слова «отчетливый». Нет проблем, если тот же самый метод по умолчанию наследуется через два родительских интерфейса, которые, в свою очередь, расширяют общий базовый интерфейс, в котором определен метод по умолчанию; метод по умолчанию просто наследуется.
2 Другие проблемы множественного наследования - такие как неоднозначности, которые могут возникать в Java с полями интерфейса, статическими методами и методами по умолчанию - технически не имеют ничего общего с проблемой Diamond (фактически, Проблема Смертельного Алмаза Смерти). Однако большая часть литературы по этому вопросу (и более ранняя версия этого ответа) в конечном итоге сводит все проблемы множественного наследования под рубрикой «Алмаз смерти». Полагаю, название слишком крутое, чтобы использовать его только в технически приемлемых случаях.