Я не думаю, что принцип «открытый / закрытый» в том виде, в котором он был представлен изначально, позволяет интерпретировать, что конечные классы могут быть расширены путем внедрения зависимостей.
В моем понимании, принцип заключается в том, чтобы не допускать прямых изменений в коде, который был введен в производство, и путь к достижению этого, в то же время позволяя модифицировать функциональность, состоит в использовании наследования реализации.
Как указывалось в первом ответе, это имеет исторические корни. Несколько десятилетий назад наследование было в пользу, тестирование разработчиков было неслыханным, а перекомпиляция кодовой базы часто занимала слишком много времени.
Кроме того, учтите, что в C ++ подробности реализации класса (в частности, приватных полей) обычно были представлены в заголовочном файле «.h», поэтому, если программисту нужно его изменить, всем клиентам потребуется перекомпиляция. Обратите внимание, что это не относится к современным языкам, таким как Java или C #. Кроме того, я не думаю, что разработчики тогда могли рассчитывать на сложные интегрированные среды разработки, способные выполнять анализ зависимостей на лету, избегая необходимости частых полных перестроений.
По своему опыту я предпочитаю делать прямо противоположное: «классы должны быть закрыты для расширения (final
) по умолчанию, но открыты для модификации». Подумайте об этом: сегодня мы предпочитаем такие методы, как управление версиями (упрощает восстановление / сравнение предыдущих версий класса), рефакторинг (что побуждает нас изменять код для улучшения дизайна, или в качестве прелюдии к введению новых функций), и тестирование разработчика , которое обеспечивает защиту при изменении существующего кода.