>>201986
Не, это не костыли, а как раз таки наоборот, оригинальный паттерн, который может быть довольно громоздким, а может и не быть. В ООП вся эта механика, которую именуете костылями, оптимизирована, автоматизирована и скрыта.
Настоящее достоинство ООП-языков в какой-то степени не в абстрактных наследовании, инкапсуляции, полиморфизме, а в куда более конкретных вещах: например в том, что не надо писать this для вызова ассоциированого с объектом метода в контексте другого такого метода, и в том, что для поддержки интерфейса вместе с этим объектом не надо явно кидать в метод структуру с указателями или явно делать для каждого такого объекта ссылку на метаданные, по которым из явно объявленного массива таких структур (aka таблицы виртуальных методов) можно выдернуть реализацию интерфейса. Весь такой boilerplate уже сделан за тебя, или так мне мало что на самом деле знающему теоретику кажется.
Хотя, в связи с ориентированностью только на один объект, ООП-языки типа Java начинают лагать, когда нужно провести сценарий над двумя объектами.
То есть, например, взять какую-нибудь Циву или Монополию, где юнит переходит на клетку, и с ним, и с клеткой от этого что-то происходит в зависимости от типа юнита и типа клетки. Тут, получается, для запуска нужного сценария по идее должна быть трёхмерная таблица виртуальных методов, что-то типа scenario[cellType, unitType](cell, unit). Но так делать нельзя, потому что инкапсуляция наше всё и менять что-то извне — грех, сравнимый с использованием goto, и потому что автоматическая таблица виртуальных методов может быть только по одному типу, а не по двум сразу.
Возникает также проблема: пихать метод наступания юнита на клетку в класс юнита или в класс клетки. Оба друг друга меняют, и главного во взаимодействии выделить нельзя. В любом случае, в таком методе будет гора if-ов типа if(unit is SettlerUnit), либо гора if(cell is SettlerManglingCell), либо разбивка на очень узкоспецифичные виртуальные методы, распиханные по разным файлам и нацеленные на взаимодействие только с конкретным типом или аспектом типа юнита/клетки, переиспользование которых без copypaste-ы при изменении типа юнита/клетки затруднительно. Полиморфизм в таком случае продаждает быть пыткой.