WEBVTT

00:00:00.480 --> 00:00:05.200 align:middle
Hello. Today we are going to examine
a very interesting subtlety

00:00:05.360 --> 00:00:07.720 align:middle
that you can apply in your programs.

00:00:07.880 --> 00:00:11.640 align:middle
To start with, we'll quickly review
the dice program.

00:00:11.800 --> 00:00:16.520 align:middle
If you recall, in this exercise
we defined the dice class in order

00:00:16.680 --> 00:00:20.840 align:middle
to define instances of this class
and represent various dice faces.

00:00:21.000 --> 00:00:24.920 align:middle
We defined a class called DiceHandle.

00:00:25.360 --> 00:00:29.440 align:middle
Then we implemented
the "plus" method

00:00:29.600 --> 00:00:31.320 align:middle
on the DiceHandle class,

00:00:31.480 --> 00:00:34.840 align:middle
to add DiceHandles
and construct a new DiceHandle.

00:00:35.000 --> 00:00:37.600 align:middle
This is the code for this class.

00:00:37.760 --> 00:00:40.680 align:middle
We have DiceHandle new.

00:00:40.840 --> 00:00:42.920 align:middle
We create a new DiceHandle,

00:00:43.080 --> 00:00:46.680 align:middle
to which we add the dice
of the receiver class

00:00:46.840 --> 00:00:48.200 align:middle
and the setting,

00:00:48.360 --> 00:00:52.040 align:middle
and we return this handle
at the end of the method. Okay?

00:00:53.280 --> 00:00:57.960 align:middle
In this sequence we will see
the difference,

00:00:58.120 --> 00:01:02.200 align:middle
in this "+" method,
between writing DiceHandle new

00:01:02.360 --> 00:01:04.840 align:middle
and self class new.

00:01:05.000 --> 00:01:07.560 align:middle
And we'll see why
one technique is better.

00:01:08.160 --> 00:01:09.840 align:middle
Here is the problem.

00:01:10.200 --> 00:01:15.440 align:middle
If I create a DiceHandle subclass
called MemoDiceHandle,

00:01:16.080 --> 00:01:20.720 align:middle
and I want to add MemoDiceHandles,

00:01:20.880 --> 00:01:24.280 align:middle
with the "+" method,
which is inherited from DiceHandle,

00:01:24.440 --> 00:01:28.600 align:middle
the result is an instance
of the DiceHandle class.

00:01:28.760 --> 00:01:30.880 align:middle
Not of the MemoDiceHandle class.

00:01:31.040 --> 00:01:33.840 align:middle
This is a problem
because when we add elements,

00:01:34.000 --> 00:01:36.720 align:middle
we want to get
the same type of element back.

00:01:36.880 --> 00:01:38.400 align:middle
How do we do this?

00:01:38.560 --> 00:01:40.080 align:middle
Solution No. 1.

00:01:40.480 --> 00:01:42.960 align:middle
I change the implementation

00:01:43.120 --> 00:01:46.080 align:middle
of the "+" method
on the DiceHandle class.

00:01:46.560 --> 00:01:48.080 align:middle
The "+" method, okay?

00:01:48.240 --> 00:01:53.280 align:middle
And I simply add this method:
self handleClass.

00:01:53.440 --> 00:01:58.320 align:middle
Instead of defining
the instance variable I wish to obtain,

00:01:58.480 --> 00:02:02.160 align:middle
I use a method
that I call handleClass.

00:02:02.320 --> 00:02:05.160 align:middle
In DiceHandle,
the DiceHandle class is returned,

00:02:05.320 --> 00:02:09.800 align:middle
and in the MemoDiceHandle subclass,
MemoDiceHandle is returned.

00:02:10.160 --> 00:02:14.480 align:middle
So by simply
redefining the handleClass method,

00:02:14.640 --> 00:02:19.720 align:middle
we obtain the correct instance
when we add elements.

00:02:21.120 --> 00:02:25.280 align:middle
If we execute the same code,

00:02:25.440 --> 00:02:30.520 align:middle
using MemoDiceHandle instead,
we get an instance of MemoDiceHandle,

00:02:30.680 --> 00:02:33.680 align:middle
because I redefined
the handleClass method

00:02:33.840 --> 00:02:38.280 align:middle
in the MemoDiceHandle class.
We got an instance of the subclass.

00:02:38.440 --> 00:02:42.160 align:middle
So we attained our objective.

00:02:42.760 --> 00:02:46.200 align:middle
The problem is that

00:02:46.360 --> 00:02:51.680 align:middle
each time we add a subclass
to DiceHandle,

00:02:51.840 --> 00:02:54.240 align:middle
we must redefine
the handleClass method.

00:02:54.400 --> 00:02:59.600 align:middle
If you don't, the "+" method will never
return the correct class instance.

00:02:59.760 --> 00:03:03.720 align:middle
This is tedious.
You must constantly redefine the method.

00:03:03.880 --> 00:03:05.080 align:middle
There are better ways.

00:03:05.600 --> 00:03:09.000 align:middle
Here's Solution No. 2.

00:03:09.160 --> 00:03:13.200 align:middle
Using the "+" method in DiceHandle,
this time we will write:

00:03:13.360 --> 00:03:16.160 align:middle
self class new.

00:03:17.000 --> 00:03:20.680 align:middle
I'll ask the current receiver
for its class,

00:03:20.840 --> 00:03:22.640 align:middle
in order to get an instance.

00:03:22.800 --> 00:03:27.240 align:middle
In fact, self class always returns
the class of the receiver.

00:03:27.400 --> 00:03:29.360 align:middle
If it's the instance of a subclass,

00:03:29.520 --> 00:03:33.520 align:middle
it will return the correct class.
For example, MemoDiceHandle.

00:03:33.680 --> 00:03:37.840 align:middle
We get instances of the same kind
as that of the receiver.

00:03:38.520 --> 00:03:40.480 align:middle
As a conclusion,

00:03:40.640 --> 00:03:42.400 align:middle
as you saw,

00:03:42.800 --> 00:03:47.040 align:middle
when you send the message "+"
to a DiceHandle,

00:03:47.200 --> 00:03:52.080 align:middle
if you set the name of the class
you want an instance for,

00:03:52.240 --> 00:03:56.760 align:middle
in a sense you prevent yourself
from creating subclasses.

00:03:56.920 --> 00:04:01.400 align:middle
But with self class new, "+" returns
an instance of the receiver.

00:04:01.560 --> 00:04:03.280 align:middle
Of the potential subclass.

00:04:03.440 --> 00:04:06.920 align:middle
So it's much better to use
self class new,

00:04:07.080 --> 00:04:09.480 align:middle
to directly get

00:04:10.120 --> 00:04:14.720 align:middle
an instance of the class
according to the type of receiver.

