Действительно ли наследство необходимо? Зависит от того, что вы подразумеваете под «действительно». Вы можете вернуться к перфокартам или теоретически переключить тумблеры, но это ужасный способ разработки программного обеспечения.
Да, в процедурных языках наследование классов является определенным благом. Это дает вам возможность элегантно организовать ваш код в определенных обстоятельствах. Он не должен быть чрезмерно использован, так как любая другая функция не должна быть чрезмерно использована.
Например, возьмем случай digiarnie в этой теме. Он / она использует интерфейсы почти для всего, что так же плохо, как (возможно, и хуже) с использованием большого количества наследования.
Некоторые из его очков:
это помогает с тестированием и улучшает читабельность
Это ничего не делает. На самом деле вы никогда не тестируете интерфейс, вы всегда тестируете объект, то есть экземпляр класса. А необходимость взглянуть на совершенно другой фрагмент кода помогает понять структуру класса? Я так не думаю.
То же самое для глубокой иерархии наследования. В идеале вы хотите посмотреть только в одном месте.
Используя интерфейсы, я получил бы тот же эффект, но я бы имитировал наследование, используя
'Делегация'.
Делегирование - очень хорошая идея, и ее часто следует использовать вместо наследования (например, шаблон «Стратегия» предназначен именно для этого). Но интерфейсы не имеют никакого отношения к делегированию, потому что вы не можете указать какое-либо поведение в интерфейсе.
также значительно упрощает рефакторинг.
Ранняя привязка к интерфейсам обычно усложняет рефакторинг, а не облегчает его, потому что тогда остается больше мест для изменений. Злоупотребление наследованием на ранних этапах лучше (ну, не так плохо), как злоупотребление интерфейсами, поскольку извлечение классов делегатов легче, если изменяемые классы не реализуют никаких интерфейсов. И это довольно часто от этих делегатов, чем вы получаете полезные интерфейсы.
Так что злоупотребление наследованием - это плохо. Злоупотребление интерфейсами - это плохо. И в идеале, класс не будет ни наследовать (кроме, может быть, «объекта» или языкового эквивалента), ни реализовывать какие-либо интерфейсы. Но это не означает, что любая из этих функций должна быть удалена из языка.