Передача сообщений - это другой способ удовлетворения потребности в ОО-коде для того, чтобы один объект заставил другой объект (или, возможно, сам) что-то сделать.
В большинстве современных языков, которые происходят от подхода C ++, мы делаем это с помощью вызовов методов. В этом случае вызываемый объект (через определение класса) помещает большой список того, что вызывает метод, который он принимает, и затем кодировщик вызывающего объекта просто записывает вызов:
public void doSomething ( String input )
...
other_object.dosomething ( local )
Для статически типизированных языков компилятор может затем проверить тип вызываемой вещи и подтвердить, что метод был объявлен. Для динамически типизированных языков это выполняется во время выполнения.
Но, по сути, происходит то, что пакет переменных отправляется в определенный блок кода.
Передача сообщений
В языках передачи сообщений (таких как Objective C) вместо методов есть приемники, но в целом подход определения и вызова их во многом аналогичен - различие заключается в способе его обработки.
На языке передаваемых сообщений компилятор может проверить, что получатель, который вы вызвали, существует, но в худшем случае он выдаст предупреждение о том, что он не уверен, что он там есть. Это происходит потому, что во время выполнения будет вызван блок кода на принимающем объекте, передающий как пакет переменных, так и сигнатуру получателя, которого вы хотите вызвать. Затем этот блок кода ищет получателя и вызывает его. Однако, если получатель не существует, тогда код просто вернет значение по умолчанию.
В результате одна из странностей, обнаруженных при переходе с C ++ / Java -> Objective C, заключается в понимании того, что вы можете «вызвать метод» для объекта, который не был объявлен в типе времени компиляции и даже не существует в тип времени выполнения ... и что вызов не будет вызывать исключение, а фактически будет возвращать результат.
Преимущества этого подхода состоят в том, что он выравнивает иерархию подкласса и устраняет большинство потребностей в интерфейсах / множественном наследовании / типах утки. Он также позволяет объектам определять поведение по умолчанию, когда их просят сделать что-то, для чего у них нет получателя (обычно «если я этого не делаю, перенаправьте запрос этому другому объекту»). Это также может упростить привязку к обратным вызовам (например, для элементов пользовательского интерфейса и синхронизированных событий), особенно в статически типизированных языках, таких как Java (так что вы можете заставить кнопку вызывать получатель «runTest», а не вызывать метод «actionPerformed» для внутреннего класса). "RunTestButtonListener", который делает вызов для вас).
Однако может показаться, что за счет необходимости дополнительной проверки разработчиком, что вызов, который они совершают, находится на правильном объекте с правильным типом и передачей правильных параметров в правильном порядке, потому что компилятор может не предупреждаю вас, и он будет отлично работать во время выполнения (просто возвращая ответ по умолчанию). Также возможно снижение производительности от дополнительного просмотра и передачи параметров.
В наши дни языки с динамической типизацией могут дать много преимуществ ОО, передаваемых сообщениями, с меньшим количеством проблем.