#oop #inheritance #foreach #polymorphism #composition
#ооп #наследование #foreach #полиморфизм #композиция
Вопрос:
Существует принцип проектирования, согласно которому вы должны отдавать предпочтение композиции перед наследованием, но разве это не правда, что это не выполняется, когда мы хотим использовать полиморфизм?
Например, если мы хотим что-то сделать для нескольких связанных объектов, мы можем захотеть выполнить итерацию по циклу for-each, указав только, что объект, выполняющий метод, является —некоторым супертипом, как мы получим эту функциональность и повторное использование кода с использованием композиции?
Ответ №1:
В статически типизированных языках, где полиморфизм связан с наследованием, это наследование может быть достигнуто двумя способами: один способ с сохранением состояния, а другой — без состояния. Это можно назвать наследованием реализации и наследованием спецификации соответственно. Например, в Java наследование классов зависит от состояния, тогда как наследование интерфейса не имеет состояния.
Имея это в виду, когда в книге «Банда четырех» говорится,
Предпочтение композиции объектов перед наследованием классов.
… они имеют в виду наследование с учетом состояния. Таким образом, полиморфизм все еще может быть достигнут с помощью наследования без состояния, следуя этому принципу, даже в статически типизированных языках.
(В динамически типизированных языках нет никакой связи между полиморфизмом и наследованием, поскольку полиморфизм не требует явных объявлений типов.)
Вот о чем беспокоилась Банда четырех.
… дизайнеры часто злоупотребляют наследованием как методом повторного использования, [но] проекты часто становятся более повторно используемыми (и более простыми), в большей степени зависящими от состава объекта.
Я часто формулирую это так: «наследование — плохой инструмент для повторного использования кода». Другими словами, не используйте наследование, чтобы сохранить ваш код СУХИМ. Композиция лучше для этого. С другой стороны, наследование без состояния не предназначено для повторного использования кода и является отличным инструментом для полиморфизма.