Заблуждаетесь. Допустим у нас есть такой код:some_obj.do_smth(1)
Здесь some_obj - это экземпляр некоторого класса. do_smth - сообщение, которое мы ему отправляем. 1 - аргумент этого сообщения.
У каждого объекта есть ссылка на класс который его породил. Когда some_obj получит сообщение do_smth он пойдёт по этой ссылке в свой класс, потому что именно в классе хранится таблица методов. Далее класс начнёт поиск сообщения в таблице. Как он будет это делать - зависит от языка. В одних он тупо использует do_smth, как ключ, в других - он учтёт количество переданных аргументов или даже их тип (т.н. перегрузка методов).
Если класс найдёт соответствующий метод, то он параметризирует его данными из объекта и из аргументов сообщения, выполнит его и отдаст результат.
Гораздо интереснее то что произойдёт когда класс метод не найдёт. Я не буду здесь учитывать наследование.
В Смолтолке класс дёрнет свой метод #doesNotUnderstand:, который по дефолту кидает исключение с текстом типа "класс такой-то не содержит метода для обработки сообщения do_smth 1". Этот метод можно переопределить и динамически перенаправить сообщение в нужный метод или другой объект. Можно например сказать - если сообщение начинается с "do" то разбей его по '_', затем дёрни метод do с аргументами smth и 1.
Этот механизм существует во всех динамически-типизированных ООП языках. В Python аналогом #doesNotUnderstand: выступает метод __getattr__, в Ruby - method_missing, в PHP - хук __call. Во всех этих языках сообщение не соответствует методу напрямую, а так же его можно хранить в переменной или создать динамически из строк. Это и есть "модель сообщений". Она даёт программисту огромные возможности и сильно упрощает реализацию большинства паттернов, но у неё есть один серьёзный недостаток - её невозможно валидировать статически.
В статически-типизированных ООП языках такая магия не приемлема - в них валидатор должен до запуска программы знать какой класс, в итоге, обработает сообщение. Поэтому в таких языках до недавних времён существовало прямое соответствие между сообщением и его методом-обработчиком. Из-за этого слово "сообщение" в этих языках вообще перестали использовать и стали говорить "мы вызываем метод do_smth у объекта some_obj". Из чего выросло ложное разделение на языки с "моделью сообщений" и языки с "моделью вызова метода". Сообщения в Java и C# никуда не делись, их можно конструировать и отправляеть в рантайме с помощью рефлексии и dynamic.