WEBVTT

00:00:00.440 --> 00:00:01.480 align:middle
Hello, everyone.

00:00:01.640 --> 00:00:03.400 align:middle
Welcome to sequence 3.

00:00:03.560 --> 00:00:06.040 align:middle
Now that we have looked at inheritance,

00:00:07.400 --> 00:00:10.400 align:middle
self, and lookup,
we'll examine "super."

00:00:10.840 --> 00:00:14.280 align:middle
We'll start by focusing on
sending a message

00:00:14.880 --> 00:00:17.840 align:middle
in cases where "super"
is the receiver.

00:00:18.360 --> 00:00:19.840 align:middle
What is "super"?

00:00:20.120 --> 00:00:25.360 align:middle
Take a few minutes to think of
a definition covering these two points:

00:00:26.040 --> 00:00:28.200 align:middle
What does "super" represent?

00:00:30.400 --> 00:00:32.200 align:middle
How is a method looked up

00:00:32.360 --> 00:00:34.240 align:middle
when a message is sent to "super"?

00:00:35.160 --> 00:00:36.560 align:middle
The following principle

00:00:36.920 --> 00:00:39.200 align:middle
is the same in both Pharo and Java.

00:00:39.560 --> 00:00:41.640 align:middle
The example you see here

00:00:42.800 --> 00:00:46.240 align:middle
is similar to the ones we saw
in earlier sequences.

00:00:46.680 --> 00:00:49.360 align:middle
"Super" is used in one method.

00:00:52.320 --> 00:00:55.600 align:middle
Let's think about what happens.

00:00:56.440 --> 00:00:57.920 align:middle
For A new bar,

00:00:59.560 --> 00:01:00.920 align:middle
there's no problem.

00:01:01.080 --> 00:01:03.120 align:middle
It's the same process as before.

00:01:03.320 --> 00:01:05.600 align:middle
The method is run,

00:01:06.160 --> 00:01:08.080 align:middle
and foo returns 10.

00:01:10.320 --> 00:01:13.440 align:middle
In the case of B new bar,
let's look at each step.

00:01:15.560 --> 00:01:17.960 align:middle
We send the message "bar"

00:01:18.360 --> 00:01:20.720 align:middle
to the B new object.

00:01:22.080 --> 00:01:24.840 align:middle
The lookup algorithm
seeks the method "bar"

00:01:25.160 --> 00:01:27.160 align:middle
starting with the object class.

00:01:27.320 --> 00:01:29.800 align:middle
It finds the method "bar."

00:01:30.880 --> 00:01:33.320 align:middle
It is executed on the receiver.

00:01:34.000 --> 00:01:38.680 align:middle
This "bar" method is the one
executed on the receiver.

00:01:40.040 --> 00:01:43.440 align:middle
Now I have to compute
"super bar"

00:01:44.200 --> 00:01:46.640 align:middle
and "self foo," and add them together.

00:01:46.880 --> 00:01:48.600 align:middle
We can do "self foo,"

00:01:48.760 --> 00:01:53.400 align:middle
"self foo" sends the message
"foo" to the object "self."

00:01:53.800 --> 00:01:55.600 align:middle
"Self" is my B new.

00:01:56.640 --> 00:02:00.080 align:middle
The only "foo" possible
is the one in class A.

00:02:01.280 --> 00:02:03.160 align:middle
So "self foo" returns 10.

00:02:04.840 --> 00:02:06.920 align:middle
In "super bar,"

00:02:08.000 --> 00:02:09.720 align:middle
"super" is the receiver.

00:02:10.440 --> 00:02:12.920 align:middle
But the lookup algorithm changes

00:02:13.120 --> 00:02:15.720 align:middle
in the presence of the receiver "super."

00:02:16.680 --> 00:02:19.840 align:middle
It will seek the method "bar"

00:02:20.320 --> 00:02:24.160 align:middle
starting with the super class
containing the keyword "super."

00:02:25.080 --> 00:02:29.200 align:middle
"Super" is located in the "bar"
method of class B.

00:02:29.640 --> 00:02:32.960 align:middle
We'll be looking for method "bar"

00:02:33.120 --> 00:02:35.680 align:middle
starting in B's superclass, which is A.

00:02:36.240 --> 00:02:40.720 align:middle
So we find this method
and that is the one executed.

00:02:41.000 --> 00:02:43.200 align:middle
Foo is sent to self.

00:02:43.360 --> 00:02:46.480 align:middle
"Self" is always the receiving object.

00:02:46.880 --> 00:02:47.880 align:middle
It is B new.

00:02:48.120 --> 00:02:51.200 align:middle
So foo is sent to the initial object.

00:02:51.560 --> 00:02:54.640 align:middle
This is the "foo" that is executed,
returning 10.

00:02:56.800 --> 00:02:58.400 align:middle
10 + 10 = 20.

00:03:00.320 --> 00:03:02.480 align:middle
In the case of C new bar,

00:03:02.920 --> 00:03:04.800 align:middle
we note C new, here.

00:03:05.120 --> 00:03:09.120 align:middle
It is an instance of class C.
We send it the message "bar."

00:03:09.800 --> 00:03:14.320 align:middle
"Bar" is sought in class C new.

00:03:14.640 --> 00:03:17.080 align:middle
Not found.
The class above is searched.

00:03:17.480 --> 00:03:18.640 align:middle
It is there, in B.

00:03:18.800 --> 00:03:22.400 align:middle
So the B new bar will be executed.

00:03:23.480 --> 00:03:27.960 align:middle
This bar is the sum
of two message-sendings.

00:03:28.640 --> 00:03:31.480 align:middle
We can start with the second.

00:03:31.640 --> 00:03:34.640 align:middle
We send the message "foo"
to the object "self."

00:03:34.880 --> 00:03:39.200 align:middle
Self is still my C New, here.
I send the message "foo."

00:03:40.120 --> 00:03:42.760 align:middle
The method is found, and 50 is returned.

00:03:44.280 --> 00:03:45.880 align:middle
I put the value 50 there.

00:03:46.440 --> 00:03:50.960 align:middle
Now we need the first part
of the sum, "super bar."

00:03:51.240 --> 00:03:55.200 align:middle
I send the message "bar"
to "super," always the receiver.

00:03:55.360 --> 00:03:58.280 align:middle
But the lookup algorithm changes.

00:03:59.000 --> 00:04:04.240 align:middle
It looks for "bar" in the superclass
for the class containing "super."

00:04:05.320 --> 00:04:08.720 align:middle
That is, "bar" method in class B.

00:04:09.000 --> 00:04:13.240 align:middle
The algorithm starts looking up "bar"
in B's superclass, which is A.

00:04:13.880 --> 00:04:15.440 align:middle
Bar is located here.

00:04:15.880 --> 00:04:17.360 align:middle
This "bar" is executed.

00:04:17.640 --> 00:04:20.920 align:middle
"Self" is still C new. Still this one.

00:04:21.080 --> 00:04:22.440 align:middle
Always the receiver.

00:04:22.760 --> 00:04:24.440 align:middle
We send it the message "foo."

00:04:24.600 --> 00:04:27.960 align:middle
The result is 50, and I have 50 here.

00:04:28.280 --> 00:04:30.960 align:middle
50 + 50 = 100.

00:04:31.680 --> 00:04:32.920 align:middle
The next slide

00:04:33.360 --> 00:04:36.640 align:middle
reviews the details
of the lookup algorithm process,

00:04:36.800 --> 00:04:38.680 align:middle
for further study.

00:04:39.680 --> 00:04:42.880 align:middle
"Super" always refers to the receiver.

00:04:43.040 --> 00:04:45.120 align:middle
It's exactly like "self,"

00:04:45.320 --> 00:04:47.200 align:middle
or "this" in Java.

00:04:47.480 --> 00:04:52.440 align:middle
Likewise, "super" in Java is like "this,"
and always refers to the receiver.

00:04:53.160 --> 00:04:57.520 align:middle
However, when a message is sent
to "super," the lookup algorithm changes

00:04:57.680 --> 00:05:01.360 align:middle
and begins searching for a method
in the superclass

00:05:01.800 --> 00:05:05.680 align:middle
of the class containing the method
being executed.

00:05:06.040 --> 00:05:09.880 align:middle
"Self" and "super" are therefore
fundamentally different.

00:05:10.320 --> 00:05:13.640 align:middle
"Self" is dynamic,
while "super" is static.

00:05:13.880 --> 00:05:15.520 align:middle
I'll explain that further.

00:05:17.080 --> 00:05:19.760 align:middle
When "foo" is sent to "self,"

00:05:20.360 --> 00:05:24.240 align:middle
the developer has no idea
which "foo" method will be executed.

00:05:24.880 --> 00:05:28.480 align:middle
It could be the "foo"
located in the same class,

00:05:29.120 --> 00:05:31.840 align:middle
or a "foo" in an existing subclass,

00:05:32.200 --> 00:05:35.640 align:middle
or a "foo" in a subclass
created by another developer

00:05:35.920 --> 00:05:38.040 align:middle
before the program is run.

00:05:38.720 --> 00:05:42.240 align:middle
When the "bar" method developer
writes "self foo,"

00:05:42.480 --> 00:05:45.640 align:middle
he has no idea which "foo"
will be executed.

00:05:46.080 --> 00:05:48.160 align:middle
That's a convenient feature.

00:05:48.480 --> 00:05:51.280 align:middle
It means developers
can create a new subclass

00:05:51.440 --> 00:05:54.320 align:middle
to change the behavior of class A.

00:05:55.440 --> 00:05:58.120 align:middle
Conversely, "super" is static.

00:05:58.880 --> 00:06:03.400 align:middle
When the developer writes "super foo,"

00:06:04.000 --> 00:06:06.920 align:middle
he knows which "foo" method
will be executed

00:06:07.080 --> 00:06:09.560 align:middle
when the program is run.

00:06:09.840 --> 00:06:13.440 align:middle
When he writes "super foo" here,
he knows he is referring

00:06:14.280 --> 00:06:16.360 align:middle
to "foo" in superclass A.

00:06:16.880 --> 00:06:18.680 align:middle
Invariably. Super is static.

00:06:18.880 --> 00:06:21.640 align:middle
We know how the program
will be compiled.

00:06:22.080 --> 00:06:25.360 align:middle
Unfortunately, certain books

00:06:25.720 --> 00:06:28.160 align:middle
define "super" wrong.

00:06:28.320 --> 00:06:30.560 align:middle
The definitions make no sense.

00:06:30.920 --> 00:06:33.800 align:middle
Here is a definition we found in a book.

00:06:34.320 --> 00:06:37.480 align:middle
It says that "super"
looks for the method...

00:06:37.920 --> 00:06:42.280 align:middle
In other words,
"super" prompts the lookup algorithm

00:06:42.440 --> 00:06:47.240 align:middle
to search for the method in
the superclass of the receiver's class.

00:06:48.000 --> 00:06:50.480 align:middle
The superclass of the receiver's class.

00:06:50.640 --> 00:06:54.360 align:middle
Actually, this is wrong,
as proved by the example shown.

00:06:54.800 --> 00:06:58.920 align:middle
If you take aC as the receiver,
its class is C.

00:06:59.720 --> 00:07:03.120 align:middle
The receiver's superclass
is therefore B.

00:07:04.040 --> 00:07:08.560 align:middle
If I come down here
and execute the command "super foo,"

00:07:08.960 --> 00:07:12.960 align:middle
if the definition given by the book
applied,

00:07:13.640 --> 00:07:16.360 align:middle
we would send the message "foo"

00:07:17.640 --> 00:07:20.520 align:middle
to "super," and the "foo"
method executed

00:07:20.680 --> 00:07:24.320 align:middle
would be the one in the superclass
of the receiver's class.

00:07:24.480 --> 00:07:27.480 align:middle
In other words, this one.

00:07:27.840 --> 00:07:30.520 align:middle
It would send "foo" to "super"

00:07:30.800 --> 00:07:34.480 align:middle
over and over again,
in an infinite loop.

00:07:35.680 --> 00:07:38.280 align:middle
So the definition is wrong.

00:07:38.440 --> 00:07:43.760 align:middle
In practice, this example functions
perfectly.

00:07:44.240 --> 00:07:46.640 align:middle
It's just that this definition is wrong.

00:07:47.280 --> 00:07:49.480 align:middle
Here's what to remember:

00:07:50.040 --> 00:07:52.440 align:middle
"Self" always represents the receiver.

00:07:52.680 --> 00:07:53.840 align:middle
So does "super."

00:07:54.000 --> 00:07:58.040 align:middle
It's the same in Java,
with "this" and "super."

00:07:58.880 --> 00:08:01.160 align:middle
However, "super" changes the lookup.

00:08:01.600 --> 00:08:05.000 align:middle
It will start looking for a match

00:08:05.240 --> 00:08:07.320 align:middle
in the superclass

00:08:07.560 --> 00:08:12.160 align:middle
of the class containing the method
that contains the keyword "super."

00:08:12.720 --> 00:08:15.240 align:middle
"Self" sends are dynamic.

00:08:15.640 --> 00:08:20.240 align:middle
The developer can use them to extend
the behavior of an existing class,

00:08:20.440 --> 00:08:23.440 align:middle
by creating a subclass
that redefines the method.

