Здравствуйте, McSeem2, Вы писали:
MS>Здравствуйте, Ramzes_, Вы писали:
R_>>Наследования, специализация, это вопрос терминологии. И термин наследование, имхо, вполне адекватно и понятно отражает данную сущность.
MS>Традиционно под наследованием понимается, что-то типа "производный класс делает все то же самое, что и базовый и плюс к тому, еще это, это и вот это". На мой взгляд, это и есть самое неправильное использование наследования. Во всяком случае, ни к чему хорошему оно никогда не приводило — получался слошной бардак и рак головы. Особенно умиляют попытки порождать производные классы от чего-то типа std::vector.
MS>Правильное использование наследования — это замещение (override) виртуальных функций. Только оно и ничего более. От этого есть безусловная польза, но это уже становится не наследованием, а специализацией. Поэтому я и говорю, что наследование как таковое является сомнительной концепцией. Какая-то она грязноватая эта концепция, с намешанными в одну кучу разными понятиями.
Согласен. Добавлю к сказанному от себя.
Чисто теоретически, множественное наследование действительно иногда может быть уместным. Это тот очень редкий случай, когда производный класс является полной суммой своих предков. Но проблема множественного наследования заключается в том, что предвидеть этот случай на этапе проектирования крайне трудно. В итоге, практика использования множественного наследования сводится к следующему сценарию:
1) На начальном этапе разработки системы во время проектирования и начале реализации активно испрользуется множественное наследование, так как специфика базовых классов еще выражена слабо и производные классы еще действительно являются полной суммой своих предков.
2) Роект живет и обрастает мегабайтами кода. Базовые классы наполняются методами все сильнее и сильнее проявляя свою специфику. И вот, в один ужасный момент приходит понимание того, что производные классы уже не являются полной суммой своих предков, а следовательно, наследование тут неуместно и надо с архитектурой что-то делать.
3) Ввиду того, что при применении наследования, и тем более, множественного наследования у нас получается весьма железобетонная архитектура (антоним гибкой), то начинаются пляски с бубном, которые выражаются в:
-- жутких архитектурных хаках
-- банальном copy/paste
-- нагромождении if/switch
На подобные шалости уже закрываются глаза, так как "проект надо было сдавать еще вчера". В итоге, код становится помойкой.
Но наследование, как и множественное наследование имеют известную альтернативу в виде интерфейсов+агрегирования+делегирования. Конечно, интерфейсы имеют свои недостатки, среди которых, например, то, что на начальном этапе реализации проекта приходится писать немного больше кода, чем если бы использовалось [множественное] наследование. Но зато, получается очень гибкая, а следовательно, и устойчивая архитектура, которая легко поддается развитию и рефакторингу.
Таким образом, я считаю нецелесообразным использование множественного наследования ввиду того, что в процессе развития проекта очень легко можно нарваться на трудноустранимые проблемы, связанные с множественным наследованием. То есть это как бомба замедленного действия. Я уверен, что лучше сразу потратить чуть-чуть больше усилий и воспользоваться интерфейсами, но потом спать спокойно.