Аргументов достаточно много:
* дочерний класс наследует все данные и поведение родительского, что нужно не всегда (а при доработке родительского в дочерний класс вообще попадают данные и поведение, которые не предполагались на момент разработки дочернего);
* виртуальные методы менее производительные, а в случае, если язык позволяет объявить невиртуальный метод, то как быть, если в наследнике нужно его перекрыть (можно пометить метод словом new, но при этом не будет работать полиморфизм, и использование такого объекта может привести к не ожидаемому поведению, в зависимости от того, к какому типу приведен объект в момент его использования);
* если возникает необходимость множественного наследования, то в большинстве языков оно отсутствует, а там, где есть (C++), считается трудоемким;
* есть задачи, где наследование как таковое не может помочь — если нужен контейнер элементов (множество, массив, список) с единым поведением для элементов разных типов, и при этом нужно обеспечить статическую типизацию, то здесь помогут обобщения (generics).
* и т.д., и т.п.
Альтернативой наследованию являются использование интерфейсов и композиция. (Интерфейсы давно используется в качестве альтернативы множественному наследованию, даже если в иерархии классов активно используется наследование.)
Декларируемым преимуществом наследования является отсутствие дублирования кода. В предметной области могут встречаться объекты с похожим или одинаковым набором свойств и методов, но имеющих частично или полностью разные поведение или механизмы реализации этого поведения. И в этом случае для устранения дублирование кода придется использовать иные механизмы.
А как можно решить эту задачу (отсутствие дублирования кода) в случае композиции и интерфейсов?
Этой теме и посвящена настоящая статья.
[Читать дальше →][1]
[1]:
https://habrahabr.ru/post/314258/?utm_source=habrahabr&utm_medium=rss&utm_campaign=feed_posts#habracut