В основном объектно-ориентированная система действительно сводится к «передаче сообщений»
На процедурном языке я вызываю функцию, подобную этой:
f(x)
И имя f, вероятно, связано с конкретным блоком кода во время компиляции. (Если это не процедурный язык с функциями более высокого порядка или указателями на функции, но давайте на секунду проигнорируем эту возможность.) Так что эта строка кода может означать только одну недвусмысленную вещь.
На объектно-ориентированном языке я передаю сообщение объекту, возможно, так:
o.m(x)
В этом случае. m - это не имя блока кода, а «селектор метода», и то, какой блок кода вызывается, в некоторой степени зависит от объекта o. Эта строка кода является более двусмысленной или общей, потому что она может означать разные вещи в разных ситуациях, в зависимости от o.
В большинстве языков ОО объект o имеет «класс», и класс определяет, какой блок кода вызывается. В паре ОО-языков (наиболее известный как Javascript) o не имеет класса, но имеет методы, непосредственно связанные с ним во время выполнения, или унаследовал их от прототипа.
Я отмечаю, что ни классы, ни наследование не нужны для того, чтобы язык был ОО. Но эта полиморфная обработка сообщений очень важна.
Хотя вы можете подделать это с помощью указателей функций, скажем, на C, этого недостаточно для того, чтобы C был назван языком OO, потому что вам придется реализовать собственную инфраструктуру. Вы можете сделать это, и стиль ОО возможен, но язык вам его не дал.