Мне всегда нравилась идея поддержки множественного наследования в языке. Чаще всего это преднамеренно, и предполагаемая «замена» - это интерфейсы. Интерфейсы просто не охватывают все то же основание, что и множественное наследование, и это ограничение может иногда приводить к дополнительному шаблонному коду.
Единственная основная причина, которую я когда-либо слышал для этого, - проблема алмазов с базовыми классами. Я просто не могу принять это. Для меня это звучит ужасно, например: «Ну, это возможно испортить, так что это автоматически плохая идея». Вы можете испортить что угодно на языке программирования, и я имею в виду все, что угодно. Я просто не могу принять это всерьез, по крайней мере, без более подробного объяснения.
Просто осознание этой проблемы - это 90% битвы. Кроме того, я думаю, что слышал что-то много лет назад о обходном пути общего назначения, включающем алгоритм «конверта» или что-то в этом роде (кто-нибудь звонит в колокол?).
Что касается проблемы с бриллиантами, единственная потенциально подлинная проблема, о которой я могу подумать, это если вы пытаетесь использовать стороннюю библиотеку и не видите, что два, казалось бы, не связанных класса в этой библиотеке имеют общий базовый класс, но в дополнение к документация, простая языковая функция, скажем, может потребовать, чтобы вы специально заявили о своем намерении создать бриллиант, прежде чем он фактически скомпилирует его для вас. С такой особенностью любое создание алмаза является либо преднамеренным, безрассудным, либо потому, что человек не знает об этой ловушке.
Так что все сказанное ... Есть ли какая-то реальная причина, по которой большинство людей ненавидят множественное наследование, или это просто кучка истерии, которая приносит больше вреда, чем пользы? Есть ли что-то, чего я здесь не вижу? Спасибо.
пример
Автомобиль расширяет WheeledVehicle, KIASpectra расширяет Car и Electronic, KIASpectra содержит радио. Почему KIASpectra не содержит Electronic?
Потому что это Электронный. Наследование против состава всегда должно быть отношением «есть» или «иметь».
Потому что это Электронный. Есть провода, платы, переключатели и т. Д. Все это вверх и вниз по этой вещи.
Потому что это Электронный. Если ваша батарея разряжается зимой, вы попадаете в такую же проблему, как если бы все ваши колеса внезапно пропали без вести.
Почему бы не использовать интерфейсы? Взять, к примеру, № 3. Я не хочу писать это снова и снова, и я действительно не хочу создавать какой-то причудливый прокси-класс помощника для этого:
private void runOrDont()
{
if (this.battery)
{
if (this.battery.working && this.switchedOn)
{
this.run();
return;
}
}
this.dontRun();
}
(Мы не понимаем, является ли эта реализация хорошей или плохой.) Вы можете себе представить, как могут быть некоторые из этих функций, связанных с Electronic, которые не связаны ни с чем в WheeledVehicle, и наоборот.
Я не был уверен, стоит ли останавливаться на этом примере или нет, так как там есть место для интерпретации. Вы могли бы также подумать о терминах, расширяющих Plane, и FlyingObject и Bird, расширяющих Animal и FlyingObject, или о более чистом примере.
Traits
- они действуют как интерфейсы с необязательной реализацией, но имеют некоторые ограничения, которые помогают предотвратить возникновение таких проблем, как проблема с бриллиантами.
KiaSpectra
не является Electronic
; у него есть электроника, и он может быть ElectronicCar
(который будет расширяться Car
...)