Задать вопрос
@rxlrxl

Расширение публичного интерфейса в наследнике, как это решается?

Всем привет.

Сразу опишу ситуацию, а потом сформулирую вопрос.

Есть класс Car, в котором полями являются компоненты Engine, Gearbox, Body и т.д. со своими публичными интерфейсами.
Допустим, мы хотим расширить публичный интерфейс компонента Body и добавить корпусу машины выдвигающийся спойлер.

Решение, которое сразу приходит в голову:

Ок, создаем наследника Body, назовем его WingedBody.
Выдвигаться этот спойлер будет исходя из какой-то логики класса Car, т.е. вызывать метод deploySpoiler() должен класс Car (а точнее его наследник).
Создаем наследника Car под названием WingedCar, и тут возникает вопрос: как пользоваться новой функциональностью класса WingedBody? Ведь от класса Car мы унаследовали поле с типом Body, а нужен нам WingedBody.

Несколько очевидных решений:
1) Вариант в лоб - приведение типа, то бишь downcasting от Body к WingedBody. Некрасиво и неэффективно.
2) Создаем дополнительное поле с типом WingedBody и новую функциональность вызываем через него. Минус - нужно поддерживать равенство обоих полей (старый с типом Body и новый c типом WingedBody должны быть одним и тем же объектом).
3) Улучшенный вариант второго решения. Создаем интерфейс IDeployableSpoiler, реализуем его в классе WingedBody, а в классе WingedCar создаем поле с типом IDeployableSpoiler а не WingedBody. Более понятное решение, но все равно мы по сути плодим лишние поля.

Есть мнение, что такая ситуация в реальной работе возникает очень редко и является ошибкой проектирования. Если вы так считаете, то обоснуйте это пожалуйста, потому что, как мне кажется, заранее всю функциональность (а соответственно и публичный интерфейс) предусмотреть невозможно (а если это либа - значит и дописать родительский класс нельзя).

Вопрос уже звучал, но повторю для наглядности. Как бы вы решали подобную задачу?
  • Вопрос задан
  • 2376 просмотров
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
maaGames
@maaGames
Погроммирую программы
У класса Car есть контейнер объектов IAerodynamics, в котором содержатся все объекты, влияющие на аэродинамику. Хочешь - добавляешь спойлер, хочешь - обвесы, хочешь - снимаешь всё.
Ответ написан
@jkotkot
режим сарказма
Не нужно использовать наследование. Продолжайте использовать агрегацию.
Машина состоит из двигателя, кузова и колес. Кузов состоит из дверей, крыльев, спойлера и так далее.
Там где спойлера нет возвращаем null. Как-то так...
Ответ написан
Комментировать
gbg
@gbg Куратор тега Программирование
Любые ответы на любые вопросы
Еще можно сделать шаблон класса car с параметрами engine, gbox и так далее. И порождать нужные сочетания машин.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы