-Dans ce cours, on verra la différence entre les méthodes et les messages.
On a vu précédemment qu'une méthode,
c'est une séquence nommée d'instructions.
Là, j'ai une méthode que j'ai imaginée pour faire des crêpes.
En fait, une méthode, c'est comme une recette de cuisine.
Je vais avoir une suite d'instructions à suivre et à exécuter.
Pour faire des crêpes, je vais mettre des œufs, du lait, du sucre et de la farine
et j'obtiens des crêpes.
C'est ma recette de cuisine pour faire les crêpes.
C'est aussi la méthode makeCrepes. C'est la même chose.
Si on regarde, toutes les instances d'une classe
vont partager le même comportement.
En fait, quand je vais envoyer un message à une instance,
je vais chercher dans la classe.
La classe contient toutes les méthodes pour ces instances.
Donc, cette méthode-là sera exécutée.
Là, quand je cherche,
j'envoie un message à une instance de la classe rectangle.
Je vais chercher la méthode aire qui est associée au message
dans la classe rectangle et je l'exécute sur le receveur du message.
Une méthode, en fait, c'est ce que je disais.
Elle définit le comportement. C'est une suite d'instructions.
Elle a un nom qui est souvent en relation avec le message.
En Pharo, c'est le nom qui déterminera la méthode qu'on devra exécuter.
Dans d'autres langages, c'est un peu différent mais c'est le même principe.
La méthode, elle, comme je le montre sur le schéma,
va pouvoir accéder à l'état propre de l'objet.
C'est une particularité, alors que le message est extérieur.
J'envoie un message à un objet. Je ne me préoccupe pas des valeurs.
Je n'ai pas accès aux valeurs internes de l'objet.
C'est la méthode qui, elle, est proche des données.
On a vu qu'une méthode, c'est comment on va faire une opération.
Comment on va répondre à un message. Et un message, c'est le quoi.
Donc, les messages, c'est quoi faire et les méthodes, c'est comment.
Donc, si on regarde les différences qu'on a,
le message va être extérieur à l'objet.
La méthode va être vraiment intérieure. Elle pourra accéder aux données.
Le message est plus abstrait, dans ce sens-là et moins opérationnel.
On veut que la chose soit faite et non pas savoir comment elle est faite.
Ça a une influence, après, sur l'encapsulation.
Je reviendrai plus tard là-dessus.
Donc le message, lui, va juste être :
"J'envoie un message à un objet avec les paramètres
et je m'attends à ce que ça soit exécuté.
J'attends que l'objet réalise ce pour quoi je l'ai invoqué."
Ce qu'il faut voir, c'est que les méthodes sont recherchées dynamiquement.
Là, j'ai deux exemples d'illustration.
Je vous ai montré l'exemple dans un cours précédent avec les animaux.
Je vais envoyer le même message à différentes instances d'objets
qui sont d'instances de différentes classes.
Quand j'envoie le message "angry" à un chien, je cherche dans la classe chien.
Quand j'envoie un message "angry" à un chat, je vais dans la classe chat.
J'ai la même chose, par exemple, sur les formes mathématiques.
Quand je demande quelle est l'aire à un rectangle,
je m'attends à ce que la classe Rectangle implémente cette fonctionnalité-là
et me dise que c'est la longueur multipliée par la largeur.
Pour le cercle, je voudrais bien avoir Pi R² et ce genre de choses.
Donc là, on voit bien que les méthodes vont dépendre des instances...
Les méthodes exécutées vont dépendre des instances
qui sont receveurs du message.
Sur cet exemple-là, on pourrait avoir une liste qui contient des formes,
à la fois des rectangles, des carrés et des cercles
et on pourrait faire la somme des aires
en envoyant le message "aire" à chacun des objets de cette liste.
Je n'ai pas à distinguer...
"J'ai un rectangle ? J'ai un carré ou un cercle ?"
J'ai simplement à envoyer le message à chaque forme
en lui disant : "Calcule ton aire" et que cette aire soit calculée.
C'est le pouvoir de la liaison tardive. On va voir ça aussi.
Donc, la liaison tardive, c'est l'idée
que la méthode qui sera exécutée sera déterminée lors de l'exécution,
que la bonne méthode sera exécutée par rapport à ça.
C'est la différence entre la programmation procédurale
et la programmation objet.
En programmation objet, on n'écrira pas de test.
On va juste donner des ordres.
Et le mécanisme de sélection des méthodes va se réaliser automatiquement
et exécuter la bonne méthode, donc celle qui correspond au receveur.
Ce mécanisme s'appelle la liaison tardive.
La liaison tardive, "late binding" en anglais, qu'est-ce que ça signifie ?
Lors de la compilation,
je ne connais pas le code qui va être exécuté.
Je sais que je vais devoir rechercher la méthode lors de l'exécution.
Des techniques d'optimisation font
que la deuxième fois qu'on cherche la même chose,
on la trouve plus rapidement, etc., mais la liaison tardive
est un mécanisme fondateur et fondamental de la programmation objet.
Je voudrais qu'on regarde l'encapsulation des données.
Je vous ai dit qu'un objet a des données qui lui sont propres
et des méthodes qui sont partagées par la classe.
Conceptuellement, on peut penser qu'un objet est un patatoïde
avec des données, au milieu, des méthodes et des messages, dehors.
J'enverrai des messages. Ça exécutera des méthodes.
Ces méthodes ont accès à des données. À quoi sert cette distinction ?
On voit sur le transparent suivant que l'encapsulation...
Moi, en tant que client, j'ignore comment c'est implémenté à l'intérieur.
Elle va me permettre de changer
et d'avoir des objets qui me proposent la même interface, le même message,
mais qui ont des implémentations différentes.
Là, par exemple, on a deux implémentations différentes
de comment on calcule l'aire d'un rectangle.
D'un point de vue de client, ça ne m'intéresse pas.
L'information n'est pas intéressante pour moi.
Je veux, quand j'envoie mon message "aire",
recevoir la bonne aire et qu'elle soit bien calculée.
Maintenant, je peux avoir deux objets qui me proposent une méthode aire
et qu'elles soient implémentées différemment.
Ça me permettra de faire évoluer mes applications dans le temps
sans avoir à tout réécrire.
Il se trouve que là, tout le code client qui était basé sur la méthode aire
est réutilisable.
Que je mette un objet
dont l'implémentation est celle du haut ou celle du bas,
qui sont deux implémentations différentes, ce n'est pas grave.
Ça signifie que le code client va continuer à marcher.
Donc, il pourra évoluer sur un plus long terme
et je n'ai pas à recompiler tout le système.
Donc, l'encapsulation des données est très importante,
car elle permettra une pérennisation, une évolution
et de cacher des détails qui ne sont pas opportuns.
Ce sont de très bonnes propriétés de la programmation objet.
En résumé, je vous ai montré
que les méthodes sont des séquences d'instructions.
Les messages représentent des ordres.
À partir de ces ordres, les méthodes seront exécutées.
Les méthodes sont partagées entre toutes les instances des classes.
On peut avoir différentes méthodes ayant le même nom.
Ce n'est pas un problème entre différentes classes.
Et je peux envoyer le même message à différents objets
qui exécuteront des méthodes différentes.
À cela s'ajoute le fait que j'aie cette distance par rapport aux données
et à la prise de décision de comment j'ai encodé mon calcul
qui fait que je pourrai faire évoluer mes objets sans impacter mes clients.
Toutes ces propriétés sont fondamentales et liées à la liaison dynamique.