WEBVTT

00:00:00.520 --> 00:00:04.240 align:middle
Bonjour à tous. Dans cette
troisième séquence, après s'être

00:00:04.440 --> 00:00:08.830 align:middle
intéressés à l'héritage et à
self et au lookup, on va s'

00:00:09.030 --> 00:00:09.790 align:middle
intéresser à super.

00:00:11.130 --> 00:00:12.690 align:middle
Dans cette séquence,
nous allons nous intéresser

00:00:12.890 --> 00:00:17.690 align:middle
particulièrement à l'envoi de messages
dans le cas où super est le receveur.

00:00:18.380 --> 00:00:19.460 align:middle
Alors qu'est-ce que super ?

00:00:20.090 --> 00:00:23.000 align:middle
Prenez quelques minutes
pour vous poser la question et

00:00:23.200 --> 00:00:24.860 align:middle
notamment répondre à ces 2 questions.

00:00:26.120 --> 00:00:28.330 align:middle
Qu'est-ce que super représente ?

00:00:30.480 --> 00:00:35.310 align:middle
Comment se passe l'envoi de
messages quand super est le receveur?

00:00:35.510 --> 00:00:39.000 align:middle
Ce que je vais vous dire ici,
c'est pareil en Pharo et en Java.

00:00:39.820 --> 00:00:44.680 align:middle
Dans cet exemple-là, qui
est proche des exemples vus

00:00:44.880 --> 00:00:48.840 align:middle
dans la séquence précédente, on
utilise super dans une des méthodes.

00:00:52.640 --> 00:00:55.470 align:middle
On va essayer de réfléchir
un peu à ce qui se passe.

00:00:56.670 --> 00:01:01.370 align:middle
Pour A new bar,
aucune difficulté, même

00:01:01.570 --> 00:01:02.530 align:middle
exemple que précédemment.

00:01:03.830 --> 00:01:08.090 align:middle
Cette méthode bar est
exécutée et Foo retourne 10.

00:01:10.380 --> 00:01:12.710 align:middle
Dans le cas de B new bar,
on va le faire étape par

00:01:15.630 --> 00:01:19.600 align:middle
étape. On envoie le
message bar à l'objet B new.

00:01:19.800 --> 00:01:24.250 align:middle
L'algorithme de
lookup cherche une méthode

00:01:24.450 --> 00:01:26.940 align:middle
bar à partir de la
 classe de cet objet.

00:01:27.440 --> 00:01:31.880 align:middle
La méthode bar est
trouvée, elle s'exécute

00:01:32.210 --> 00:01:36.660 align:middle
sur le receveur. Donc c'est
cette méthode bar là qui est

00:01:36.860 --> 00:01:38.350 align:middle
exécutée sur le receveur.

00:01:40.420 --> 00:01:44.910 align:middle
Il faut maintenant que je
calcule super bar, self foo et

00:01:45.110 --> 00:01:46.010 align:middle
que je fasse la somme des 2.

00:01:47.140 --> 00:01:48.110 align:middle
On peut faire self foo.

00:01:48.310 --> 00:01:52.780 align:middle
Self foo envoie le
message foo à l'objet

00:01:53.000 --> 00:01:55.580 align:middle
self. Self, c'est mon B new.

00:01:56.020 --> 00:02:00.190 align:middle
Il n'y a qu'un seul foo possible,
c'est celui qui est dans la classe A.

00:02:01.320 --> 00:02:02.080 align:middle
Self foo retourne 10.

00:02:04.870 --> 00:02:09.270 align:middle
Super bar : super, c'est le

00:02:09.470 --> 00:02:13.310 align:middle
receveur. Par contre,
l'algorithme de lookup change en

00:02:13.510 --> 00:02:15.530 align:middle
présence du receveur super.

00:02:16.730 --> 00:02:21.550 align:middle
On v a chercher la
méthode bar à partir de la super

00:02:21.750 --> 00:02:23.390 align:middle
 classe de là où se
trouve le mot-clé super.

00:02:25.350 --> 00:02:29.930 align:middle
Super se trouve dans la
méthode bar de la classe B, donc

00:02:30.130 --> 00:02:34.080 align:middle
on va chercher une
méthode bar à partir de la super

00:02:34.280 --> 00:02:35.040 align:middle
 classe de B, c'est-à-dire A.

00:02:36.550 --> 00:02:40.780 align:middle
On trouve cette méthode-là et c'est
cette méthode-là qui est exécutée.

00:02:41.000 --> 00:02:43.230 align:middle
Donc foo est envoyé à self.

00:02:43.480 --> 00:02:47.630 align:middle
Self, c'est toujours le même objet,
c'est toujours le receveur, c'est B new.

00:02:48.130 --> 00:02:53.000 align:middle
Foo est donc envoyé sur
l'objet initial et donc c'est ce

00:02:53.200 --> 00:02:57.210 align:middle
foo-là qui est
exécuté qui retourne 10.

00:02:57.410 --> 00:02:58.250 align:middle
10 et 10 : 20.

00:03:00.380 --> 00:03:04.280 align:middle
Dans le cas de C new bar,
on a notre C new qui est ici

00:03:04.480 --> 00:03:08.950 align:middle
qui est une instance de la classe
 C et on lui envoie le message bar.

00:03:09.870 --> 00:03:13.270 align:middle
Bar est cherché dans la
 classe de C new, c'est-à-dire C.

00:03:14.700 --> 00:03:16.230 align:middle
Il n'est pas trouvé là,
il est cherché au-dessus.

00:03:17.550 --> 00:03:22.110 align:middle
Il est trouvé là, c'est donc
ce bar là qui va être exécuté.

00:03:23.530 --> 00:03:27.680 align:middle
Ce bar là est la somme
de 2 envois de messages.

00:03:28.720 --> 00:03:32.550 align:middle
On peut commencer par le
second encore une fois, on

00:03:32.750 --> 00:03:34.410 align:middle
envoie le message foo à l'objet self.

00:03:34.880 --> 00:03:37.660 align:middle
Self, c'est toujours
mon C new qui est ici.

00:03:38.130 --> 00:03:39.170 align:middle
J'envoie le message foo.

00:03:40.170 --> 00:03:41.000 align:middle
Cette méthode-là est trouvée.

00:03:41.480 --> 00:03:45.400 align:middle
50 est retourné, là j'ai 50.

00:03:46.490 --> 00:03:49.640 align:middle
Super bar, maintenant il
nous manque la première partie

00:03:49.840 --> 00:03:51.530 align:middle
de l'addition de super bar.

00:03:51.730 --> 00:03:53.720 align:middle
J'envoie le message bar à super.

00:03:53.920 --> 00:03:56.540 align:middle
Super, c'est toujours le
receveur mais l'algorithme de

00:03:56.740 --> 00:04:00.690 align:middle
lookup change et va
chercher bar à partir de la super

00:04:00.890 --> 00:04:03.930 align:middle
 classe de là où se trouve
l'expression qui contient

00:04:04.130 --> 00:04:07.920 align:middle
super, c'est-à-dire la méthode
bar de la classe B, c'est-à-dire

00:04:08.130 --> 00:04:11.600 align:middle
la classe B, donc on
commence à chercher bar à partir de

00:04:11.800 --> 00:04:12.620 align:middle
la super classe de B, c'est-à-dire A.

00:04:12.820 --> 00:04:14.700 align:middle
Bar est trouvé ici.

00:04:14.900 --> 00:04:17.310 align:middle
Ce bar là est exécuté.

00:04:17.650 --> 00:04:20.880 align:middle
Self, c'est toujours C
new, c'est toujours celui-là,

00:04:21.160 --> 00:04:24.040 align:middle
toujours le receveur et on
lui envoie le message foo.

00:04:24.700 --> 00:04:29.430 align:middle
On tombe sur 50.
Ici j'ai 50: 50 et 50,

00:04:30.720 --> 00:04:31.480 align:middle
100.

00:04:31.890 --> 00:04:35.280 align:middle
Dans ce slide, vous avez les
détails de l'exécution de l'algorithme

00:04:35.590 --> 00:04:38.570 align:middle
pour pouvoir réviser et
retravailler cet exemple.

00:04:39.710 --> 00:04:44.060 align:middle
Super référence toujours le
receveur, c'est exactement

00:04:44.460 --> 00:04:47.100 align:middle
comme self ou comme this en Java.

00:04:47.300 --> 00:04:50.100 align:middle
Et pareil, super en Java,
c'est comme this en Java, ça

00:04:50.300 --> 00:04:51.250 align:middle
représente toujours le receveur.

00:04:53.220 --> 00:04:56.340 align:middle
Par contre lorsqu'un message
est envoyé à super, l'algorithme

00:04:56.540 --> 00:04:59.790 align:middle
de lookup change et
commence à chercher une méthode à

00:05:00.000 --> 00:05:02.920 align:middle
partir de la super classe,
de la classe qui contient la

00:05:03.120 --> 00:05:05.230 align:middle
méthode en train d'être
exécutée dans laquelle super se trouve.

00:05:06.100 --> 00:05:11.000 align:middle
Self et super ont donc une
différence fondamentale: self

00:05:11.200 --> 00:05:13.880 align:middle
est dynamique tandis
que super est statique.

00:05:14.120 --> 00:05:15.150 align:middle
Qu'est-ce que je veux dire par là ?

00:05:17.140 --> 00:05:20.510 align:middle
Je veux dire que quand
foo est envoyé à self, le

00:05:20.710 --> 00:05:23.680 align:middle
développeur n'a aucune idée de la
méthode foo qui va être exécutée.

00:05:24.930 --> 00:05:27.950 align:middle
Ça peut être le foo qui se
trouve dans la même classe,

00:05:29.920 --> 00:05:32.860 align:middle
dans une sous-classe
existante ou dans une sous-classe

00:05:33.080 --> 00:05:37.750 align:middle
qui sera créée par un autre
développeur avant l'exécution du programme.

00:05:38.760 --> 00:05:41.880 align:middle
Donc lorsque le développeur
de la méthode bar écrit self

00:05:42.080 --> 00:05:45.140 align:middle
foo, il n'a aucune idée de la
méthode foo qui va être exécutée.

00:05:46.260 --> 00:05:48.660 align:middle
C'est particulièrement
pratique, ça veut dire que les

00:05:48.860 --> 00:05:51.330 align:middle
développeurs peuvent créer
de nouvelles sous-classes pour

00:05:51.530 --> 00:05:54.440 align:middle
changer le
comportement de la classe A.

00:05:55.500 --> 00:05:58.200 align:middle
Super, à l'inverse, est statique.

00:05:58.910 --> 00:06:03.240 align:middle
Lorsque le
développeur écrit "Super foo",

00:06:04.070 --> 00:06:06.550 align:middle
il sait quelle est la
méthode foo qui sera exécutée

00:06:07.500 --> 00:06:09.740 align:middle
lorsque le programme sera exécuté.

00:06:09.940 --> 00:06:14.820 align:middle
Donc en écrivant ça, il
sait que ça sera cette méthode

00:06:15.020 --> 00:06:16.210 align:middle
foo-là qui sera exécutée.

00:06:16.890 --> 00:06:20.110 align:middle
Toujours. Super est
statique, à la compilation on sait

00:06:20.310 --> 00:06:21.330 align:middle
quelle méthode sera exécutée.

00:06:23.200 --> 00:06:27.000 align:middle
Malheureusement, certains
livres se trompent dans la

00:06:27.200 --> 00:06:30.210 align:middle
définition de super et donnent des
définitions qui n'ont pas de sens.

00:06:31.000 --> 00:06:34.460 align:middle
Voici une définition qu'on
a trouvée dans un livre et

00:06:34.660 --> 00:06:39.400 align:middle
dans cette définition-là,
on nous dit que super cherche

00:06:40.720 --> 00:06:42.920 align:middle
la méthode. Donc
l'algorithme de lookup quand il voit

00:06:43.120 --> 00:06:46.140 align:middle
super va chercher la méthode à
partir de la super classe du receveur.

00:06:48.040 --> 00:06:50.080 align:middle
Donc la super classe de
la classe du receveur.

00:06:50.410 --> 00:06:51.680 align:middle
En fait cette définition est fausse.

00:06:52.210 --> 00:06:55.580 align:middle
Si on prend l'exemple
ci-dessous, si on prend comme

00:06:55.780 --> 00:06:58.570 align:middle
receveur AC, sa classe c'est C.

00:06:59.740 --> 00:07:02.750 align:middle
La super classe du
receveur c'est donc B.

00:07:04.060 --> 00:07:08.240 align:middle
Et si ici, j'exécute cette partie-là

00:07:09.020 --> 00:07:12.120 align:middle
avec la définition qui est
donnée plus haut et qui est

00:07:12.320 --> 00:07:16.210 align:middle
fausse, on enverrait le message foo

00:07:16.880 --> 00:07:20.720 align:middle
à super, et la méthode foo
qui serait exécutée, c'est la

00:07:20.920 --> 00:07:23.840 align:middle
méthode foo qui se trouve
dans la super classe de la

00:07:24.040 --> 00:07:27.950 align:middle
 classe du receveur,
c'est-à-dire cette méthode foo là qui

00:07:28.150 --> 00:07:30.930 align:middle
exécuterait ça, qui
enverrait le message foo à super, qui

00:07:31.130 --> 00:07:33.400 align:middle
exécuterait ça, et cetera.
Et donc on voit ici qu'on a

00:07:33.600 --> 00:07:38.010 align:middle
une boucle infinie, c'est
bien que la définition est

00:07:38.210 --> 00:07:42.100 align:middle
fausse parce que dans la pratique cet
exemple n'est pas une boucle infinie.

00:07:42.300 --> 00:07:43.540 align:middle
Cet exemple fonctionne parfaitement.

00:07:44.620 --> 00:07:47.430 align:middle
Et donc la
définition est juste fausse.

00:07:47.630 --> 00:07:51.440 align:middle
Ce que de vous devez
retenir: Self représente toujours

00:07:51.640 --> 00:07:53.710 align:middle
le receveur ainsi que Super.

00:07:54.100 --> 00:07:58.120 align:middle
Et c'est pareil en Java, This et
Super représentent toujours le receveur.

00:07:58.940 --> 00:08:01.030 align:middle
Par contre, Super change
l'algorithme de lookup.

00:08:01.690 --> 00:08:04.450 align:middle
L'algorithme de lookup
va chercher une méthode

00:08:04.650 --> 00:08:08.100 align:middle
correspondante à partir de
la super classe de la classe

00:08:08.300 --> 00:08:12.140 align:middle
qui contient la méthode,
qui contient le mot-clé Super.

00:08:12.770 --> 00:08:16.090 align:middle
Les envois de messages à
Self sont dynamiques, et on peut

00:08:16.290 --> 00:08:19.150 align:middle
s'en servir en tant que
développeur pour étendre le

00:08:19.350 --> 00:08:21.370 align:middle
comportement d'une classe
existante en faisant une

00:08:21.570 --> 00:08:23.300 align:middle
sous-classe, qui
redéfinit une méthode.

