ООП. Часть 1. Simula. 👨‍🎓👨‍💻



Недавно под одним моим постом завязалась интересная дискуссия касаемо ООП. Вдохновившись ей я решил написать пост про то как появилось ООП и как было реализовано в первых ОО языках.



Самым первым языком внедрившем понятия ООП была Simula-67. Признаюсь честно, я не писал на этом языке, хотя он был в моей университетской программе. Несложно догадаться по названию, что этот ЯП был реализован в 1967 году, задолго до появления C++ и Java. Увы, язык не смог снискать большой популярности, но оказал огромное влияние на развитие идей ООП.



Окей, давайте разбираться с Simula. Признаться, когда я готовил этот пост и погрузился в более детальное изучение этого ЯП я немного прифигел. Тут вам и автоматическое управление память с Mark&Sweep сборщиком мусора; классы и объекты, наследование, полиморфизм подтипов, виртуальные методы; поддержка параллельных вычислений; примитивные типы данных; статическая типизация...



Звучит очень похоже на Java? А то. Только вот Simula вышла в 67, а Java в 95. И повторюсь, Simula была первым ОО языком в мире. Одним словом блестящая новаторская работа, которая безусловно опередила своё время.



Давайте посмотрим на встроенные типы данных в ЯП:



1. Числа представлены несколькими типами: Integer, Real, LongReal.



2. Для работы со строками есть специальный тип Text. Строки в Simula поддерживают динамическую длину и изменяемость.



3. Логический тип.



4. Массивы фиксированной длины. Массив не является объектом. Поддерживаются многомерные массивы.



5. Ссылочный тип Ref(Class) для объектов.



Порефлексируем. У нас получается два мира данных:



- Одни "примитивные", т.е. имеют конкретное представление в памяти и не имеют методов.



- Объекты, которые всегда располагаются в куче и передаются по ссылке. Обратите внимание, что массив не является объектом.



Это все очень похоже на то, что мы видим в большинстве современных ОО языках навроде Java, C#, JS и т.д. Но, в отличии, от современных ЯП у нас нет автобоксинга примитивных типов в объекты. Т.е. мы не можем передавать примитивы, там где ожидаются объекты. У примитивов нет "свойств" и "методов".



Теперь давайте разбираться с ООП. Вообще, Simula поддерживает и обычное процедурное программирование. Т.е. хочешь писать без классов и объектов - да легко. Это нам уже напоминает JS и Python.



Т.к. язык статически типизирован, то каждый объект должен иметь свой явно описанный тип. Для этого были придуманы классы. Фактически, классы из Simula чертовски похожи на то, с чем мы привыкли работать. Объект создается с помощью класса и оператора New.



Классы можно наследовать от других классов, а методы - переопределять. Сами методы реализуются через таблицу виртуальных методов. Поддерживается полиморфизм подтипов, т.е. если процедура ожидает объект класса А, то также можно передать любой объект подкласса А.



Вот небольшой пример.



Class Vehicle;

Begin

Procedure move;

Begin

OutText("Vehicle is moving.");

OutImage;

End;

End;



Class Car(Vehicle);

Begin

Procedure move;

Begin

OutText("Car is driving.");

OutImage;

End;

End;



Procedure TestMovement(v : Vehicle);

Begin

v.move;

End;



! Создание объектов

Ref(Vehicle) v;

Ref(Car) c;



v :- New Vehicle;

c :- New Car;



! Тестирование движения

TestMovement(v);

TestMovement(c);




Подводя итог можно сказать, что современные ОО языки не сильно то и ушли от идей Simula. Да, они стали богаче и выразительней и сахарней. Где-то даже строже. Но основные концепции остались неизменны.



ООП стало новым витком эволюции императивного программирования, но пока еще не сформировало свою философию. Классы и объекты симула можно рассматривать как новый инструмент структурной организации кода и управления памятью. Simula звучит для 67 года как язык из будущего. Блестящая работа. Аплодирую визионерству создателей.



А на этом все. В следующем посте я продолжу свой рассказ про ООП, но уже на примере другого ЯП, который также очертил, укрепил философию ООП и возвел её в абсолют, где "все есть объект". Мы будем говорить о Smalltalk.



Всем базы! 🚀