A passagem de mensagens é uma maneira diferente de lidar com a necessidade no código OO de um objeto fazer com que outro objeto (ou potencialmente ele mesmo) faça alguma coisa.
Na maioria das linguagens modernas que descendem da abordagem C ++, fazemos isso com chamadas de método. Nesse caso, o objeto chamado (por meio de sua definição de classe) coloca uma grande lista do método que ele aceita e, em seguida, o codificador do objeto que chama chama simplesmente a chamada:
public void doSomething ( String input )
...
other_object.dosomething ( local )
Para linguagens de tipo estaticamente, o compilador pode verificar o tipo de coisa que está sendo chamada e confirmar que o método foi declarado. Para idiomas digitados dinamicamente, isso é realizado em tempo de execução.
Mas, em essência, o que acontece é que um pacote de variáveis é enviado para um bloco de código específico.
Passagem de mensagem
Em linguagens de transmissão de mensagens (como o Objetivo C), em vez de métodos, existem receptores, mas, de maneira geral, a abordagem para defini-los e chamá-los é praticamente a mesma - a diferença é a maneira como são manipulados.
Em uma linguagem transmitida por mensagem, o compilador pode verificar se o destinatário que você chamou existe, mas, na pior das hipóteses, ele exibirá um aviso para dizer que não tem certeza de que está lá. Isso ocorre porque, em tempo de execução, o que acontecerá é que um bloco de código no objeto receptor será chamado passando o pacote de variáveis e a assinatura do destinatário que você deseja chamar. Esse bloco de código procura o receptor e o chama. No entanto, se o receptor não existir, o código simplesmente retornará um valor padrão.
Como resultado, uma das esquisitices encontradas ao passar de C ++ / Java -> Objetivo C é entender que você pode "chamar um método" em um objeto que não foi declarado no tipo de tempo de compilação e nem sequer existia em o tipo de tempo de execução ... e que a chamada não resultaria em uma exceção, mas na verdade um resultado seria devolvido.
As vantagens dessa abordagem são que elas nivelam a hierarquia da subclasse e evitam a maioria das necessidades de interfaces / herança múltipla / tipos de patos. Ele também permite que os objetos definam o comportamento padrão quando solicitados a fazer algo para o qual eles não têm um receptor (normalmente "se eu não fizer isso, encaminhe a solicitação para esse outro objeto"). Ele também pode simplificar a vinculação a retornos de chamada (por exemplo, para elementos da interface do usuário e eventos programados), especialmente em linguagens de tipo estatístico, como Java (para que o botão chame o receptor de "runTest" em vez de chamar o método "actionPerformed" na classe interna "RunTestButtonListener", que faz a chamada para você).
No entanto, parece que está à custa da necessidade de verificação adicional pelo desenvolvedor de que a chamada que eles pensam estar fazendo está no objeto certo com o tipo certo e passando os parâmetros certos na ordem certa, porque o compilador pode não avisá-lo e ele funcionará perfeitamente bem em tempo de execução (retornando apenas uma resposta padrão). Também há, sem dúvida, um impacto no desempenho com a pesquisa extra e a passagem de parâmetros.
Atualmente, os idiomas digitados dinamicamente podem oferecer muitos benefícios da mensagem passada OO com menos problemas.