Чем больше я узнаю о различных парадигмах программирования, таких как функциональное программирование, тем больше начинаю сомневаться в разумности таких концепций ООП, как наследование и полиморфизм. Я впервые узнал о наследовании и полиморфизме в школе, и в то время полиморфизм казался прекрасным способом написания универсального кода, который позволял легко расширяться.
Но перед лицом типизации утки (как динамической, так и статической) и функциональных функций, таких как функции высшего порядка, я начал рассматривать наследование и полиморфизм как наложение ненужных ограничений, основанных на хрупком наборе отношений между объектами. Общая идея полиморфизма заключается в том, что вы пишете функцию один раз, а позже вы можете добавить новые функции в вашу программу, не изменяя исходную функцию - все, что вам нужно сделать, - это создать еще один производный класс, который реализует необходимые методы.
Но этого гораздо проще достичь с помощью утилитарной типизации, будь то динамический язык, такой как Python, или статический язык, такой как C ++.
В качестве примера рассмотрим следующую функцию Python, за которой следует ее статический эквивалент C ++:
def foo(obj):
obj.doSomething()
template <class Obj>
void foo(Obj& obj)
{
obj.doSomething();
}
Эквивалент ООП будет выглядеть примерно так:
public void foo(DoSomethingable obj)
{
obj.doSomething();
}
Основное различие, конечно, заключается в том, что версия Java требует создания интерфейса или иерархии наследования, прежде чем она заработает. Таким образом, версия Java требует больше работы и является менее гибкой. Кроме того, я считаю, что большинство реальных иерархий наследования несколько нестабильны. Мы все видели надуманные примеры фигур и животных, но в реальном мире, когда меняются бизнес-требования и добавляются новые функции, трудно выполнить какую-либо работу, прежде чем вы действительно захотите расширить отношения «есть» между подклассы, или переделать / реорганизовать вашу иерархию, чтобы включить дополнительные базовые классы или интерфейсы для соответствия новым требованиям. С типизацией утки вам не нужно беспокоиться о моделировании чего-либо - вы просто беспокоитесь о функциональности, которая вам нужна.
Тем не менее наследование и полиморфизм настолько популярны, что я сомневаюсь, что было бы большим преувеличением назвать их доминирующей стратегией для расширяемости и повторного использования кода. Так почему наследование и полиморфизм так безумно успешны? Я пропускаю некоторые серьезные преимущества, которые наследование / полиморфизм имеют по сравнению с типизацией утки?
obj
нетdoSomething
метода? Возникает ли исключение? Ничего не происходит?