Все потоки
Поиск
Написать публикацию
Обновить

Всегда ли наследование должно идти от родителя к потомкам?

Возможно, этот вопрос уже давно обсосан кучей способов, но я дошел до него только сейчас: всегда ли наследование должно идти от родителя к потомкам?

Стандартно во всяких учебниках для начинающих рассказывают, что наследование является аналогом связи «Является». Например, яблоко является фруктом, поэтому в коде класс Яблока должен наследоваться от класса Фрукт.

Что еще нужно учитывать, чтобы усомниться в утвердительном ответе на вопрос в заголовке?

  1. Наследник может изменять методы родителя

  2. Наследник может хранить больше полей, чем родитель

  3. Наследник не может удалять поля родителя

Что получается тогда? Возьмем пример с геометрическими фигурами. Есть у нас прямоугольник, площадь которого вычисляется по формуле S=ab. Получается, что в прямоугольнике нам нужно два поля — стороны a и b. Но есть квадрат, который является прямоугольником, поэтому и класс Квадрат должен наследоваться от класса Прямоугольник. Проблемы, с учетом правил выше, возникают уже на этом этапе: если формула площади квадрата S=a^2, то зачем нам хранить дополнительно сторону b, которая равна стороне a? Получается, что мы впустую тратим память.

Если пойти еще выше по родителям, то прямоугольник является параллелограммом. Площадь параллелограмма вычисляется по формуле S=ab*sinQ, где Q - угол между сторонами. Получается, что в прямоугольнике и, следовательно, в квадрате нам тоже нужно хранить этот угол, а использовать его мы никак не будем. Снова тратим память впустую.

Другим видом параллелограмма является ромб (S=a^2*sinQ), в котором мы снова бесполезно храним размерность второй стороны.

И если так подумать, то параллелограмм является выпуклым прямоугольником, который вписывается в окружность. В общем случае S = sqrt[(p-a)(p-b)(p-c)(p-d)], где p = (a + b + c + d) / 2. Получается, что в параллелограмме нужно хранить не только две стороны и угол, которые затем тянутся выше, но и еще две стороны, которые также тянутся выше. Вот и получается, что в квадрате у нас хранятся отдельно все четыре стороны и угол между двумя из них.

Рассматривая наследование как метод расширения функционала, здесь гораздо «правильнее» в качестве родителя выбрать квадрат. Он хранит всего лишь одну сторону.

Далее от него потомки идут в две стороны.

Сторона первая: квадрат ->  ромб (добавляем угол) -> параллелограмм (добавляем вторую сторону)
Сторона вторая: квадрат -> прямоугольник (добавляем вторую сторону) -> выпуклый четырехугольник (добавляем еще две стороны)

Как будто, это выглядит более логично? Или я где-то ошибся? Очень жду профессионального мнения в комментариях

Теги:
+5
Комментарии4

Публикации

Ближайшие события