@vetalmatitskiy
testing engineer

Наследование в ООП — стоит ли широко применять?

доброго дня, уважаемые гуру программирования
освежал недавно своё понимание базовых принципов ООП столкнулся с резкой критикой наследования как базового принципа . серьёзные люди очень рекомендуют минимизировать наследование в своём коде. при этом большинство книг всячески расхваливают наследование и создают длинные цепочки наследования для иллюстрации этого принципа. также этой темой любят злоупотреблять во множестве ВУЗов строя длинные иерархии наследования.
Подскажите, пожалуйста, часто ли в реальных проектах Вы используете наследование от библиотечных и своих классов в коде. Или же, по другой рекомендации вызываете из собственного класса метод другого объекта. Практикуете ли генерализацию собственных классов или же начинаете кодировать классы от самых базовых?
  • Вопрос задан
  • 5696 просмотров
Пригласить эксперта
Ответы на вопрос 8
Melkij
@Melkij
PostgreSQL DBA
Я не гуру, но в реальный проектах рулят "Рефакторинг" М.Фаулера, "Совершенный код" Макконнела, "Приемы объектно-ориентированного проектирования" Э. Гамма.

Наследование, не наследование - определяется задачей и сложностью кода. Что-то красиво и изящно делается наследованием, где-то оно наоборот всё усложняет.
Ответ написан
Комментировать
Комментировать
Deerenaros
@Deerenaros
Программист, математик, задрот и даже чуть инженер
Наследование действительно следует избегать. Вообще, идеально избегать так, будто наследования нет вовсе, будто это чит-код при использовании которого пролетариат убивает котёнка.

Почему так? Давай-те представим, что мы всё и вся наследуем. Тогда объект будет... Очень ёмким, ведь он связан непосредственным родством со всеми предками (равно как и предки - со всеми наследниками). И связность будет очень и очень сильной, что очень сильно усложнит архитектуру. Чаще намного целесообразнее просто включать объект в класс (агрегировать). Во-первых, это значительно упростит архитектуру. Во-вторых, цепочка конструкторов может быть очень длинной. И лишний раз создавать объект - не лучшая идея. В-третьих, наследованием мы как бы декларируем, что вот этот класс объектов так же является вот этим классом. Далеко не всегда это верно, что в дальнейшем породит множество костылей и боль. Тогда как ошибившись с агрегацией мы всегда сможем в дальнейшем расширить до наследования несколькими изменениями.
Ответ написан
Как по мне, не стоит ударяться в крайности. Добавляйте столько уровней иерархии, сколько будете использовать. Пример избыточного наследования: liquid->alcohol->beer. Если в вашем приложении есть только пиво разных марок, то от классов liquid и alcohol вы можете отказаться, но если вы в дальнейшем заведомо будете добавлять, например класс vodka, у которого будет общий функционал с beer, то класс alcohol можете оставить, то же самое касается и класса liquid, если в приложении будет например water или juice. Неоспоримое преимущество наследования - полиморфизм, чтобы когда вы дали своему человечку в приложении разные напитки, неважно сок это или пиво, он смог использовать их по применению. Всегда задавайте себе вопрос: "А зачем?" при проектировании своего приложения и избежите излишних абстракций и функционала.

P.S. Пример упрощен до безобразия, чтобы можно было акцентировать внимание на нужных моментах.
Ответ написан
Комментировать
Foror
@Foror
Графоман
Есть области, где без наследования не обойтись, например, в разработке GUI, когда у классов есть очень много общего - события от мыши, размеры, координаты и т.д. В программировании игр, тоже самое, у игровых персонажей есть куча общего, поэтому такие вещи лучше делать через наследование.

Но это нужно уметь совмещать с композицией, т.е. не пихать в родительский класс всё подряд, а выносить в отдельные классы. Тем самым код родительского класса будет проще и наследование будет проще пониматься. Например, если у монстров есть поведение - AI, то нет нужды пихать методы AI в класс монстра, лучше создать для этого отдельный класс AI и сделать его отдельным полем в классе монстра.

А еще лучше AI сделать как внешний сервис, который ожидает на входе игровые объекты. Тем самым класс монстра даже и знать не будет о существовании AI, и тем самым код будет проще в понимании.
Ответ написан
ProgramCodePav
@ProgramCodePav
Front-end developer. Love open source
Привет. Реальных проектов указать не могу, но наследование нужно применять, когда нужно расширение класса, как вида. Например: от класса Животное наследуются классы Собака, кошка и т.д. Также следует помнить о интерфейсах (java/c#) или множественном наследовании (c++,etc), которые расширяют возможности класса.

Неплохо бы уточнить конкретную ситуацию для примера или язык программирования. Однако...

Скажу про Java, а в комментариях подскажите для всех ли языков такое используется:
Надо понимать, что во время создания объекта (оператор new, допустим - new ChildClass() ) сначала вызывается конструктор класса ChildClass. Если ChildClass является наследником другого класса, например ParentClass, то конструктор ParentClass также вызывается при создании объекта наследника (ChildClass). Вероятно, по этой причине не советуют делать длинные линейки наследования.

По поводу общего объекта - любой класс является наследником какого-либо общего корневого класса (например, object).

UPD: да, кажется, для всех ЯП такой же принцип работы конструкторов:)
Ответ написан
Комментировать
@lookid
Почитайте про object oriented design и data oriented design. Если вы пишете рантаемное приложение на ограниченной памяти, например в геимдеве. То вам придется избавляться от абстракций, виртуальных функций и прочего, в угоду производительности. Если же у вас БД c JavaEE, то навряд ли у вас будет 100500 уровней абстракции. В конечном счете важнее как вы пишете код, а не какую супер-запутанную абстракцию можете нагородить.
Ответ написан
Комментировать
@angry_bender
PHP, JS
С точки зрения практики, глубокая иерархия наследования может усложнить модульное тестирование. Кроме того, неудачная архитектура иерархии классов может противоречить правилу подстановки Лисков.
Еще, на мой взгляд, это повышает связность программы, что не всегда желательно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы