Множественное наследование в Java

Java не разрешает наследование от нескольких классов (все же допускает наследование от нескольких интерфейсов), я знаю, что это очень похоже на классическую проблему с алмазом. Но мои вопросы: почему java не допускает множественного наследования, такого как C ++, когда нет двусмысленности (и, следовательно, нет шансов на проблему с бриллиантом) при наследовании от нескольких базовых классов?


person Silent Warrior    schedule 11.08.2009    source источник
comment
Если вам нужны миксины (= хорошие части MI) на языке jvm, взгляните на scala.   -  person Kim Stebel    schedule 12.08.2009
comment
По моему опыту, множественное наследование может сделать код очень хрупким. Гораздо полезнее использовать интерфейсы. Если вы хотите повторно использовать логику реализации, используйте делегирование. Современные IDE, такие как Eclipse, упрощают делегирование работы от одного класса к другому.   -  person JohnnySoftware    schedule 02.01.2010
comment
Для тех, кто ищет подробную статью о миксинах, вот она . Как говорится в статье, нужен только 1 интерфейс, если классы не нуждаются в услугах друг от друга. Если это так, просто прочтите 2-й раздел.   -  person MattC    schedule 23.03.2013
comment
@JohnnySoftware Множественное наследование делает код хрупким, но множественное наследование интерфейсных классов делает код хорошим?   -  person curiousguy    schedule 02.11.2015


Ответы (8)


Это было дизайнерское решение Java. Вы никогда этого не получите, так что не беспокойтесь об этом слишком сильно. Хотя MI может помочь вам создавать миксины, это единственный хороший MI, который когда-либо сделает вам.

person Randolpho    schedule 11.08.2009

Я читал, что большинство программистов неправильно используют множественное наследование. «Просто продолжайте и наследуйте от класса, чтобы повторно использовать код» - не лучшая практика в случае множественного наследования.

Многие программисты не знают, когда в большинстве случаев использовать простое наследование. Множественное наследование следует использовать с осторожностью и только в том случае, если вы знаете, что делаете, если вы хотите иметь хороший дизайн.

Я не думаю, что отсутствие множественного наследования в java (как в C ++) наложит ограничения на ваш код / ​​дизайн приложения / отображение проблемной области в классы.

person Andreas    schedule 11.08.2009

если java поддерживает множественное наследование, тогда это может повлиять на другие функции java. Рассмотрим метод super (), который используется для вызова конструктора суперкласса. если программа имеет несколько суперклассов (из-за множественного наследования), то компилятор запутается, какой суперкласс конструктор класса должен быть вызван и выдать ошибку

person code_and_die    schedule 15.06.2013

Простота. Чтобы процитировать Тома Синтеса,

Команда разработчиков Java стремилась сделать Java:

  • Простой, объектно-ориентированный и знакомый
  • Надежный и безопасный
  • Архитектура нейтральная и портативная
  • Высокая производительность
  • Интерпретируемый, многопоточный и динамический

Причины отказа от множественного наследования в языке Java в основном связаны с «простой, объектно-ориентированной и знакомой» целью. Создателям Java как простого языка был нужен язык, который большинство разработчиков могло бы понять без серьезной подготовки. С этой целью они работали над тем, чтобы сделать язык как можно более похожим на C ++ (знакомым), не перенося излишнюю сложность C ++ (простой).

По мнению дизайнеров, множественное наследование вызывает больше проблем и путаницы, чем решает. Таким образом, они сокращают множественное наследование от языка (так же, как они сокращают перегрузку операторов). Обширный опыт дизайнеров C ++ научил их, что множественное наследование не стоит головной боли.

person Rose Perrone    schedule 06.04.2012

Так решили Java-дизайнеры. Множественное наследование можно моделировать с помощью интерфейсов.

person Truncarlos    schedule 27.11.2012

Один простой ответ заключается в том, что все классы в Java являются производными от java.lang.Object IIRC. Итак, у вас будет всегда проблема с бриллиантом ... :-D

person Massa    schedule 11.08.2009
comment
Не совсем. Родитель- ›Ребенок-› Объект. Итак, Parent extends Child, Child extends Object, в последнем случае это просто не написано явно, поскольку это подразумевается автоматически. - person Adam Batkin; 11.08.2009
comment
@Massa: проблема с алмазом возникает, когда в нескольких базовых классах (от которых происходит дочерний класс) имеется несколько реализаций одного и того же метода. Если мы не переопределяем методы, определенные в классе java.lang.Object, то, по сути, это не приводит к двусмысленности и проблеме с ромбами. - person Silent Warrior; 12.08.2009
comment
Если мы не переопределяем методы, определенные в java.lang.Object, я переопределяю toString, hashcode и равно гораздо чаще, чем мне нужно множественное наследование - person Pavel Feldman; 13.08.2009
comment
@Silent_Warrior: и нет, просто того факта, что вы можете вызывать метод на любом из встроенных экземпляров дедушки и бабушки, достаточно, чтобы создать проблему с проблемой алмаза. Предположим, у вас есть база - ›D1, база -› D2, DD - ›D1 и D2. Теперь предположим, что у Base есть целочисленный атрибут, называемый состоянием. И что у вас есть метод m1, который в версии D1 увеличивает состояние, НО в версии D2 увеличивает состояние ДВАЖДЫ. Каково значение атрибута состояния в переменной DD после многократного вызова такого метода? - этот пример хорошо согласуется с toString, hashcode и equals, как @Pavel, упомянутый выше - person Massa; 17.08.2009
comment
Проблем с диамоном нет. - person curiousguy; 02.11.2015

Верно, что Java не использовалась для поддержки множественного наследования реализации (только типа, то есть интерфейса). Это было дизайнерское решение.

Однако, начиная с Java 8, он поддерживает множественное наследование с использованием методов по умолчанию. См. http://docs.oracle.com/javase/tutorial/java/IandI/multipleinheritance.html:

Множественное наследование реализации - это возможность наследовать определения методов от нескольких классов. С этим типом множественного наследования возникают проблемы, такие как конфликты имен и неоднозначность. ... Методы по умолчанию представляют одну из форм множественного наследования реализации.

person Mircea Baja    schedule 31.10.2015
comment
Конфликт имен из-за наследования интерфейсов (вырожденных классов) тоже может возникнуть. - person curiousguy; 02.11.2015

Проблема ромба возникает, когда несколько родительских классов определяют свои собственные реализации чего-либо, а дочерний класс этих двух должен иметь дело с неоднозначностью того, какую реализацию использовать. Так что, если все классы в Java являются производными от Object, это единственный родительский класс. «Единственный родитель, несколько производных классов» - это не то же самое, что «Несколько родителей, один производный класс».

person Fed up    schedule 11.03.2011
comment
Нет. Проблема ромба относится к нескольким базовым классам, совместно использующим один базовый класс, а не членам с тем же именем. - person curiousguy; 02.11.2015