Парадигма объектно-ориентированного программирования появилась довольно давно и впервые была реализована в языке Simula. В принципе, для того чтобы писать в объектно ориентированном стиле совершенно не обязательно иметь поддержку со стороны языка. Верно и обратное, никакая поддержка в языке не заставит вас писать в объектно ориентированной парадигме. Для этого недостаточно разбить программу на классы, в рантайме создавать объекты и вызывать у них метода, представляя что вы передаете сообщения. Смысл объектно ориентированного программирования я вижу в другом. Программа создается как граф, вершинами которого являются объекты, а ребрами связи позволяющие передавать информацию от одного объекта к другому. У такой программы есть вход и выход, она получает данные от пользователя, производит вычисления отправляя результаты от вершины к вершине по ребрам графа и на выводит результат. Для того, чтобы программа была гибкой, то есть могла обрабатывать большое разнообразие входных данных при этом имея ограниченный набор классов. Понятно, что не ограничивая набор классов мы получим для каждого набора данных свой класс выполняющий вычисления. Так как часто наборы данных связаны между собой, изменяя правила обработки связанных наборов нам надо будет менять множество классов. И это не очень хорошо и поэтому желательно, чтобы мы могли комбинировать классы для получения результата. Таким образом желательно, чтобы объекты как слова в предложении могли идти в разном порядке предавая разный смысл высказыванию. И где здесь находятся предметно ориентированные языки и желательно чтобы классы были словарем этого языка, а графы объектов - программы были бы предложениями на этом языке. И использую это предложение можно было бы получать смысл, некий результат вычислений.

Такое на практике я видел очень редко. Чаще встречается другое использование ооп. Классы заменяют наборы switch утверждений по типу объекта, объединяя в одном классе несколько функций можно избавиться от всех переключателей по коду и легко можно добавить еще один случай в во все переключатели. Бывает что программа создается как большой агрегат, в который можно добавлять детали. И тут объекты выступают как неплохие модули для упрощения навигации по коду, но программа от этого не становится объектно ориентированной и вы с таким же успехом можете сделать все методы статичными, особенно когда все ваши объекты синглтоны.