2009-02-10 2 views
2

Я изучал концепцию множественного наследования (прошло почти 10 лет с тех пор, как я кодировал C++ в гневе и просто интересовался концепцией). Я нашел это reference в Википедии.Несколько кривых наследования

Одна критика MI, которую они перечисляют, - «Невозможно явно наследовать несколько раз из одного класса». Я смущен этим утверждением, а не на 100% уверен, что это значит.

Несомненно, наследование класса описывает структуру класса и наследует несколько раз из того же класса, что просто повторяет один и тот же контракт класса, поэтому я не могу понять, какую выгоду он даст для оправдания критики. Является ли явное наследование множественными экземплярами функций класса и свойств?

Я хотел бы понять, о чем идет речь эта критика, и почему она неявно недоступна для языков с множественным наследованием.

ответ

1

Я думаю, что они означают, что класс Car не может наследовать от своих четырех колес (например, наследовать четыре раза класс колеса). [См. Раздел С ++ на той же странице в Википедии]

Однако, я думаю, что это «упущение» на самом деле является положительной функцией, потому что наследование существует, чтобы выразить подтипирование, и нет «множественного подтипирования из одного типа». Это «явное множественное наследование» было бы не лучше простой композиции.

+0

Это то, что я тоже думал, отсюда мое замешательство. Я согласен с тем, что было бы неправильно включать его в качестве «функции», поскольку это, безусловно, противоречит моему пониманию OO. – johnc

+0

«_class Автомобиль не может наследовать от своих четырех колес (например, наследовать в четыре раза класс Wheel_». Ну, он может, просто а не напрямую. Забавная идея.;) – curiousguy

1

Аналогичным образом я не кодировал C++ в гневе более 5 лет, переключившись на C#. Я не могу вспомнить, много ли я использовал множественное наследование, но я не пропущу его, особенно, когда я могу кодировать интерфейсы и что в наши дни я использую композицию.

Однако в the best OO book ever - возможно;) - Бетран Мейер делает хорошую защиту множественного наследования. Он также делает аналогичную защиту here.

0

На самом деле, в C++ класс может наследовать несколько раз из того же класса:

класса А {};

класс B: public A();

класс C: public A();

clsss D: public B, public C {};

Теперь D заканчивается двумя копиями A. Это, как правило, считается «плохой идеей», а C++ обеспечивает виртуальное наследование для управления им.

+0

Нет, это не так. «Наследование диалогов» указано как отдельный вопрос на связанной странице Википедии. –

1

Я думаю, что проблема связана с этой конкретной статьей в Википедии. Он содержит более одного неудобного или неопределенного заявления, такого как эти драгоценности:

Tcl допускает использование нескольких родительских классов - их серийный номер влияет на разрешение имен для членов класса.

и

Однако эти шесть языков позволяют классам наследовать от нескольких интерфейсов, воссоздавая некоторые из упомянутых проблем, избегая при этом других.

Я, откровенно говоря, не знаю, что автор наметил по предложению в вашем вопросе. Это еще один пример неопределенности в плохо написанной статье, ИМХО.

6

Это называется Diamond Problem. Большинство современных языков, которые позволяют MI, имеют для этого решение.

Короче говоря, у вас есть этот класс дерево:

class A { public int f = 0; }; 

class B extends A { f = 1; }; 

class C extends A { f = 2; }; 

class D extends B, C {}; 

Что D.f печать? Если вы поместите какое-то значение в D.f, где его следует хранить? Должны ли два поля B (A) .f и C (A) .f быть объединены в один или должны оставаться отдельно? Если вы переопределите метод x из A в B и на C, что должно делать D.x()? Назовите оба? В каком порядке? Как насчет возвращаемого значения?

+0

На каком языке? – curiousguy

1

Множественное наследование - это GOTO объектно-ориентированного программирования. Он возник из-за подходов, принятых ранними OAG langauges (C++ и т. Д.). Это хорошо работает в правой руке, но это путает большинство других времен.

Одной из главных целей ООП было повторное использование поведения. Это оказалось химерой. Полезно в некоторых случаях, но в остальных случаях мы действительно заинтересованы в определении того, как взаимодействуют объекты. Посмотрите, как много шаблонов в Design Patterns используют интерфейс, а не наследование.

Реализация интерфейсов, за которыми следует явное агрегирование, являются более понятными и удобными способами выполнения тех же действий, что и множественное наследование. Почти у всех ООП есть некоторый метод определения интерфейса, почти все ООП могут объединять объекты вместе. Однако ООП обрабатывает проблемы, возникающие из-за множественного наследования (проблема с алмазами и т. Д.) Различными способами. Подобно GOTO, когда вы просматриваете код с помощью нескольких iheritance, неясно, что происходит. Однако, как и GOTO, он может быть полезен в разных обстоятельствах.

Для меня основное внимание при использовании любой сложной языковой конструкции заключается в том, должен ли я поддерживать приложение в течение длительного времени. Если я это сделаю, то я предпочел бы самый ясный, более удобный подход, даже если сейчас требуется немного больше программирования. Как и все остальное, это призвание. Обратите внимание, что большую часть времени мы завершаем программу, которую мы разработали намного дольше, чем когда-либо планировали.

+0

'goto' на самом деле является полезным инструментом. Нет никаких оснований для запрета 'goto'. Или любая причина, чтобы избежать ИМ. – curiousguy

Смежные вопросы