WEBVTT

00:00:07.280 --> 00:00:11.520 align:middle
みなさん、こんにちは。
今日の授業では

00:00:11.680 --> 00:00:14.520 align:middle
前にやった super について

00:00:14.680 --> 00:00:16.440 align:middle
理解しているか確認しようと思います。

00:00:16.680 --> 00:00:19.440 align:middle
しっかり考えてください。

00:00:19.600 --> 00:00:22.480 align:middle
理解しているかどうかテストします。

00:00:23.360 --> 00:00:25.080 align:middle
これで何を学ぶのかというと

00:00:25.240 --> 00:00:27.520 align:middle
super について

00:00:27.680 --> 00:00:29.960 align:middle
メッセージ探索について

00:00:30.120 --> 00:00:32.240 align:middle
そしてクラスメソッドについて
復習します。

00:00:32.400 --> 00:00:35.520 align:middle
1回の授業としては分厚い内容ですが
楽しんでください。

00:00:36.360 --> 00:00:42.040 align:middle
Dice クラスにメソッドを定義して

00:00:42.200 --> 00:00:44.560 align:middle
また、new メソッドを次のように
再定義するとします。

00:00:44.720 --> 00:00:47.800 align:middle
これがそのコードです。

00:00:47.960 --> 00:00:50.960 align:middle
inst := super new.

00:00:51.120 --> 00:00:52.840 align:middle
inst initialize.
^ inst

00:00:53.000 --> 00:00:56.920 align:middle
ここで、Dice new を実行すると

00:00:57.960 --> 00:01:01.560 align:middle
ここで問題です。

00:01:01.720 --> 00:01:05.320 align:middle
この表現式での inst は何でしょう？

00:01:05.480 --> 00:01:07.120 align:middle
super とは何でしょう？

00:01:07.280 --> 00:01:09.280 align:middle
super new とは何でしょう？

00:01:09.720 --> 00:01:14.120 align:middle
数秒の間に考えてみてください。

00:01:16.600 --> 00:01:19.000 align:middle
少しだけヒントをあげます。

00:01:20.040 --> 00:01:23.560 align:middle
今まで教えてきた経験からくるヒントです。

00:01:24.400 --> 00:01:28.200 align:middle
super はスーパークラスではありません。

00:01:28.360 --> 00:01:30.360 align:middle
そんな考えは頭の中から
追い出してください。

00:01:30.520 --> 00:01:33.560 align:middle
inst はスーパークラスのインスタンス
ではありません。

00:01:33.720 --> 00:01:38.200 align:middle
そんなことになったら
そのクラスのインスタンスを作れません。

00:01:38.760 --> 00:01:40.440 align:middle
では inst は何でしょう？

00:01:41.120 --> 00:01:42.120 align:middle
ちょっと掘り下げてみましょう。

00:01:42.280 --> 00:01:44.200 align:middle
super についての講義の中で

00:01:44.360 --> 00:01:47.000 align:middle
super はメッセージのレシーバーだと
言いました。

00:01:47.440 --> 00:01:50.800 align:middle
self と同様、super も
メッセージのレシーバーを指します。

00:01:50.960 --> 00:01:52.840 align:middle
これは Pharo 特有の話ではありません。

00:01:53.000 --> 00:01:56.920 align:middle
Java や C# のような他の
オブジェクト指向言語に共通したことです。

00:01:57.760 --> 00:01:59.040 align:middle
もちろん Smalltalk でも。

00:01:59.840 --> 00:02:03.400 align:middle
ここでメッセージは Dice new です。

00:02:03.560 --> 00:02:07.040 align:middle
レシーバーは何でしょう？
構文的に言って、Dice ですね。

00:02:07.200 --> 00:02:09.880 align:middle
Dice クラスです。

00:02:10.040 --> 00:02:14.720 align:middle
これらのヒントを使って
考えてみてください。

00:02:16.160 --> 00:02:17.280 align:middle
では見てみましょう。

00:02:18.160 --> 00:02:21.560 align:middle
メッセージ探索の動作を憶えていますか？

00:02:21.720 --> 00:02:24.000 align:middle
インスタンスにメッセージを送ります。

00:02:24.160 --> 00:02:26.000 align:middle
例えば、色付きの矩形
（ColoredRectangle）に。

00:02:26.160 --> 00:02:29.480 align:middle
ColoredRectangle クラスに

00:02:29.640 --> 00:02:32.880 align:middle
そのメソッドが定義されているかを見ます。
定義されていません。

00:02:33.040 --> 00:02:35.680 align:middle
area は定義されていません。
ここにあります。

00:02:35.840 --> 00:02:40.120 align:middle
見つけた定義を適用します。

00:02:40.280 --> 00:02:42.600 align:middle
何に適用するのでしょう？
レシーバーにです。

00:02:43.280 --> 00:02:46.320 align:middle
これで、このメソッドが何をするのか
わかります。

00:02:46.480 --> 00:02:51.560 align:middle
Dice class に new がないか探します。

00:02:51.720 --> 00:02:56.760 align:middle
探索して、Dice に適用します。

00:02:56.920 --> 00:02:59.480 align:middle
もっとよく見てみましょう。

00:02:59.640 --> 00:03:01.440 align:middle
前に説明した通り

00:03:01.600 --> 00:03:05.600 align:middle
Pharo では 1 回のメソッド探索で
1 回だけメッセージが送られます。

00:03:05.760 --> 00:03:09.560 align:middle
どんなオブジェクトであれ
オブジェクトにメッセージを送ると

00:03:09.720 --> 00:03:12.600 align:middle
必ずそのクラスから探索します。
このリンクを辿るということです。

00:03:12.760 --> 00:03:14.160 align:middle
そしてこのリンクを辿っていきます。

00:03:14.320 --> 00:03:16.320 align:middle
常にこの 2 つのステップを踏みます。

00:03:16.480 --> 00:03:18.720 align:middle
どういうことかというと

00:03:18.880 --> 00:03:21.640 align:middle
前に言った通り
super はレシーバーです。

00:03:22.920 --> 00:03:25.320 align:middle
レシーバーは Dice です。

00:03:26.000 --> 00:03:31.000 align:middle
したがって、Dice class の
スーパークラスから new を探索します。

00:03:31.160 --> 00:03:34.680 align:middle
大事なのは、これは Dice class であって
Dice ではないということです。

00:03:34.840 --> 00:03:36.960 align:middle
後で図で説明します。

00:03:37.120 --> 00:03:39.520 align:middle
新しい new を見つけたら

00:03:39.680 --> 00:03:42.640 align:middle
それをレシーバーに適用します。
レシーバーは Dice です。

00:03:42.800 --> 00:03:44.680 align:middle
new を Dice に適用すると

00:03:44.840 --> 00:03:47.200 align:middle
何をするのでしょう？

00:03:47.360 --> 00:03:51.800 align:middle
Dice の新しいインスタンスを生成して
初期化します。

00:03:51.960 --> 00:03:54.240 align:middle
inst は
その新しいインスタンスになります。

00:03:54.400 --> 00:03:55.920 align:middle
ダイスです。

00:03:56.360 --> 00:03:58.760 align:middle
そしてそれを初期化して返します。

00:03:58.920 --> 00:04:01.640 align:middle
では図を見てみましょう。

00:04:01.800 --> 00:04:04.240 align:middle
new を Dice に送ると

00:04:04.400 --> 00:04:07.960 align:middle
どこを見るでしょう？
どのクラスを見るのでしょう？

00:04:08.120 --> 00:04:09.760 align:middle
Dice class を見ます。

00:04:10.440 --> 00:04:12.720 align:middle
ここに
かの有名な new メソッドがあります。

00:04:12.880 --> 00:04:16.920 align:middle
そして何をするのでしょう？
super はどんなものだったかというと

00:04:18.720 --> 00:04:21.800 align:middle
super は Dice クラスです。
ここでのレシーバーです。

00:04:21.960 --> 00:04:23.840 align:middle
このオブジェクトに
メッセージを送ります。

00:04:25.400 --> 00:04:27.680 align:middle
super は
その式を持っているクラスの

00:04:27.840 --> 00:04:31.440 align:middle
スーパークラスから探す
という指示です。

00:04:31.600 --> 00:04:36.720 align:middle
したがって、Dice class の
スーパークラスを見ます。

00:04:36.880 --> 00:04:39.760 align:middle
ここを探索します。
そして上のほうを見ていきます。

00:04:39.920 --> 00:04:41.200 align:middle
するとどこかで

00:04:41.360 --> 00:04:42.920 align:middle
new が定義されています。

00:04:43.080 --> 00:04:44.360 align:middle
探索の結果

00:04:44.520 --> 00:04:46.920 align:middle
メソッドはここで定義されていて

00:04:47.080 --> 00:04:51.960 align:middle
そのメソッドをレシーバーに適用します。
Dice に適用します。

00:04:52.120 --> 00:04:55.480 align:middle
すると新しいインスタンスが得られます。
ここに書いておきます。

00:04:55.640 --> 00:04:58.120 align:middle
インスタンスが返ってきます。ダイスです。

00:04:58.280 --> 00:05:02.000 align:middle
そして inst は
この新しいインスタンスを指します。

00:05:03.000 --> 00:05:05.400 align:middle
つまり、inst は新しいダイスです。

00:05:06.040 --> 00:05:10.680 align:middle
inst に initialize メッセージを
送って、そしてそれを返します。

00:05:10.840 --> 00:05:15.760 align:middle
この例題はゴチャゴチャとなりがちです。
回りくどいですからね。

00:05:15.920 --> 00:05:19.840 align:middle
ちゃんと理解しているかどうか判るように
わざとそうしています。

00:05:20.000 --> 00:05:21.920 align:middle
2 つの事が混ざっています。

00:05:22.080 --> 00:05:23.880 align:middle
1 つは super です。

00:05:24.040 --> 00:05:29.040 align:middle
super という式を含むクラスの
スーパークラスを見るということです。

00:05:29.200 --> 00:05:31.440 align:middle
super が指すのはレシーバーです。

101 align:middle
00:05:31,600 --> 00:05:35,240
2 つ目は、new です。
new はオブジェクトを生成するメソッドです。

00:05:35.400 --> 00:05:37.120 align:middle
この例ではこの 2 つが
組み合わさっていることで

00:05:37.280 --> 00:05:40.080 align:middle
理解するのが難しくなっています。

00:05:40.240 --> 00:05:43.520 align:middle
この授業を復習することをお勧めします。

00:05:43.680 --> 00:05:45.640 align:middle
とても重要な内容だからです。

00:05:45.800 --> 00:05:46.920 align:middle
繰り返しますが

00:05:47.080 --> 00:05:50.240 align:middle
super はメッセージのレシーバーです。

00:05:50.400 --> 00:05:53.160 align:middle
この場合、Dice です。

00:05:53.320 --> 00:05:57.560 align:middle
Dice クラスのスーパークラスから
new メソッドを探します。

00:05:57.720 --> 00:06:02.320 align:middle
それをレシーバーであるDice に適用して
インスタンスの生成をします。

00:06:03.120 --> 00:06:04.280 align:middle
いいですか？

00:06:05.760 --> 00:06:11.080 align:middle
まとめると、メッセージ送信は
レシーバーのクラスからメソッドを探索します。

00:06:11.240 --> 00:06:13.080 align:middle
メッセージ送信のたびに探索を実行します。

00:06:13.240 --> 00:06:15.960 align:middle
Pharo でやることはそれだけです。
簡単ですね。

00:06:16.160 --> 00:06:20.400 align:middle
これで、super はその式を持つクラスの
スーパークラスから探索するという

00:06:20.560 --> 00:06:22.680 align:middle
意味だということを理解できたはずです。

00:06:22.880 --> 00:06:26.440 align:middle
そして super はレシーバーであり
レシーバーがクラスの場合もあります。

00:06:26.880 --> 00:06:30.160 align:middle
これで終わりではありません。
もう 1 つ問題があります。

00:06:30.320 --> 00:06:33.520 align:middle
Pharo を勉強するぐらいだから
何かに挑戦するのが好きですよね？

00:06:33.680 --> 00:06:37.520 align:middle
さあ、次の問題を考えてみましょう。

00:06:37.680 --> 00:06:41.120 align:middle
メソッドに
super class

00:06:41.280 --> 00:06:42.880 align:middle
== self class
と書いてあるとします。

00:06:43.040 --> 00:06:46.520 align:middle
この == はどういう意味かというと
ポインタが同一かどうかの比較です。

00:06:46.680 --> 00:06:49.800 align:middle
意味としては

00:06:49.960 --> 00:06:53.200 align:middle
この super class で
得られるオブジェクトは

00:06:53.360 --> 00:06:56.160 align:middle
self class で得られるオブジェクトと
同一のものか、ということです。

00:06:56.360 --> 00:06:59.760 align:middle
このメソッドは true か false の
どちらかを返します。

00:06:59.920 --> 00:07:01.280 align:middle
では問題です。

00:07:01.440 --> 00:07:05.200 align:middle
A new foo の結果は何でしょう？

00:07:05.360 --> 00:07:07.600 align:middle
A の新しいインスタンスを作って

00:07:07.760 --> 00:07:11.360 align:middle
foo メッセージを送ります。
つまりこのメッセージを評価します。

00:07:11.520 --> 00:07:13.600 align:middle
結果は何でしょう？その理由は？

00:07:13.760 --> 00:07:17.120 align:middle
答えは自分で考えてみてください。
私から正解は教えません。

