1 00:00:07,280 --> 00:00:11,520 みなさん、こんにちは。 今日の授業では 2 00:00:11,680 --> 00:00:14,520 前にやった super について 3 00:00:14,680 --> 00:00:16,440 理解しているか確認しようと思います。 4 00:00:16,680 --> 00:00:19,440 しっかり考えてください。 5 00:00:19,600 --> 00:00:22,480 理解しているかどうかテストします。 6 00:00:23,360 --> 00:00:25,080 これで何を学ぶのかというと 7 00:00:25,240 --> 00:00:27,520 super について 8 00:00:27,680 --> 00:00:29,960 メッセージ探索について 9 00:00:30,120 --> 00:00:32,240 そしてクラスメソッドについて 復習します。 10 00:00:32,400 --> 00:00:35,520 1回の授業としては分厚い内容ですが 楽しんでください。 11 00:00:36,360 --> 00:00:42,040 Dice クラスにメソッドを定義して 12 00:00:42,200 --> 00:00:44,560 また、new メソッドを次のように 再定義するとします。 13 00:00:44,720 --> 00:00:47,800 これがそのコードです。 14 00:00:47,960 --> 00:00:50,960 inst := super new. 15 00:00:51,120 --> 00:00:52,840 inst initialize. ^ inst 16 00:00:53,000 --> 00:00:56,920 ここで、Dice new を実行すると 17 00:00:57,960 --> 00:01:01,560 ここで問題です。 18 00:01:01,720 --> 00:01:05,320 この表現式での inst は何でしょう? 19 00:01:05,480 --> 00:01:07,120 super とは何でしょう? 20 00:01:07,280 --> 00:01:09,280 super new とは何でしょう? 21 00:01:09,720 --> 00:01:14,120 数秒の間に考えてみてください。 22 00:01:16,600 --> 00:01:19,000 少しだけヒントをあげます。 23 00:01:20,040 --> 00:01:23,560 今まで教えてきた経験からくるヒントです。 24 00:01:24,400 --> 00:01:28,200 super はスーパークラスではありません。 25 00:01:28,360 --> 00:01:30,360 そんな考えは頭の中から 追い出してください。 26 00:01:30,520 --> 00:01:33,560 inst はスーパークラスのインスタンス ではありません。 27 00:01:33,720 --> 00:01:38,200 そんなことになったら そのクラスのインスタンスを作れません。 28 00:01:38,760 --> 00:01:40,440 では inst は何でしょう? 29 00:01:41,120 --> 00:01:42,120 ちょっと掘り下げてみましょう。 30 00:01:42,280 --> 00:01:44,200 super についての講義の中で 31 00:01:44,360 --> 00:01:47,000 super はメッセージのレシーバーだと 言いました。 32 00:01:47,440 --> 00:01:50,800 self と同様、super も メッセージのレシーバーを指します。 33 00:01:50,960 --> 00:01:52,840 これは Pharo 特有の話ではありません。 34 00:01:53,000 --> 00:01:56,920 Java や C# のような他の オブジェクト指向言語に共通したことです。 35 00:01:57,760 --> 00:01:59,040 もちろん Smalltalk でも。 36 00:01:59,840 --> 00:02:03,400 ここでメッセージは Dice new です。 37 00:02:03,560 --> 00:02:07,040 レシーバーは何でしょう? 構文的に言って、Dice ですね。 38 00:02:07,200 --> 00:02:09,880 Dice クラスです。 39 00:02:10,040 --> 00:02:14,720 これらのヒントを使って 考えてみてください。 40 00:02:16,160 --> 00:02:17,280 では見てみましょう。 41 00:02:18,160 --> 00:02:21,560 メッセージ探索の動作を憶えていますか? 42 00:02:21,720 --> 00:02:24,000 インスタンスにメッセージを送ります。 43 00:02:24,160 --> 00:02:26,000 例えば、色付きの矩形 (ColoredRectangle)に。 44 00:02:26,160 --> 00:02:29,480 ColoredRectangle クラスに 45 00:02:29,640 --> 00:02:32,880 そのメソッドが定義されているかを見ます。 定義されていません。 46 00:02:33,040 --> 00:02:35,680 area は定義されていません。 ここにあります。 47 00:02:35,840 --> 00:02:40,120 見つけた定義を適用します。 48 00:02:40,280 --> 00:02:42,600 何に適用するのでしょう? レシーバーにです。 49 00:02:43,280 --> 00:02:46,320 これで、このメソッドが何をするのか わかります。 50 00:02:46,480 --> 00:02:51,560 Dice class に new がないか探します。 51 00:02:51,720 --> 00:02:56,760 探索して、Dice に適用します。 52 00:02:56,920 --> 00:02:59,480 もっとよく見てみましょう。 53 00:02:59,640 --> 00:03:01,440 前に説明した通り 54 00:03:01,600 --> 00:03:05,600 Pharo では 1 回のメソッド探索で 1 回だけメッセージが送られます。 55 00:03:05,760 --> 00:03:09,560 どんなオブジェクトであれ オブジェクトにメッセージを送ると 56 00:03:09,720 --> 00:03:12,600 必ずそのクラスから探索します。 このリンクを辿るということです。 57 00:03:12,760 --> 00:03:14,160 そしてこのリンクを辿っていきます。 58 00:03:14,320 --> 00:03:16,320 常にこの 2 つのステップを踏みます。 59 00:03:16,480 --> 00:03:18,720 どういうことかというと 60 00:03:18,880 --> 00:03:21,640 前に言った通り super はレシーバーです。 61 00:03:22,920 --> 00:03:25,320 レシーバーは Dice です。 62 00:03:26,000 --> 00:03:31,000 したがって、Dice class の スーパークラスから new を探索します。 63 00:03:31,160 --> 00:03:34,680 大事なのは、これは Dice class であって Dice ではないということです。 64 00:03:34,840 --> 00:03:36,960 後で図で説明します。 65 00:03:37,120 --> 00:03:39,520 新しい new を見つけたら 66 00:03:39,680 --> 00:03:42,640 それをレシーバーに適用します。 レシーバーは Dice です。 67 00:03:42,800 --> 00:03:44,680 new を Dice に適用すると 68 00:03:44,840 --> 00:03:47,200 何をするのでしょう? 69 00:03:47,360 --> 00:03:51,800 Dice の新しいインスタンスを生成して 初期化します。 70 00:03:51,960 --> 00:03:54,240 inst は その新しいインスタンスになります。 71 00:03:54,400 --> 00:03:55,920 ダイスです。 72 00:03:56,360 --> 00:03:58,760 そしてそれを初期化して返します。 73 00:03:58,920 --> 00:04:01,640 では図を見てみましょう。 74 00:04:01,800 --> 00:04:04,240 new を Dice に送ると 75 00:04:04,400 --> 00:04:07,960 どこを見るでしょう? どのクラスを見るのでしょう? 76 00:04:08,120 --> 00:04:09,760 Dice class を見ます。 77 00:04:10,440 --> 00:04:12,720 ここに かの有名な new メソッドがあります。 78 00:04:12,880 --> 00:04:16,920 そして何をするのでしょう? super はどんなものだったかというと 79 00:04:18,720 --> 00:04:21,800 super は Dice クラスです。 ここでのレシーバーです。 80 00:04:21,960 --> 00:04:23,840 このオブジェクトに メッセージを送ります。 81 00:04:25,400 --> 00:04:27,680 super は その式を持っているクラスの 82 00:04:27,840 --> 00:04:31,440 スーパークラスから探す という指示です。 83 00:04:31,600 --> 00:04:36,720 したがって、Dice class の スーパークラスを見ます。 84 00:04:36,880 --> 00:04:39,760 ここを探索します。 そして上のほうを見ていきます。 85 00:04:39,920 --> 00:04:41,200 するとどこかで 86 00:04:41,360 --> 00:04:42,920 new が定義されています。 87 00:04:43,080 --> 00:04:44,360 探索の結果 88 00:04:44,520 --> 00:04:46,920 メソッドはここで定義されていて 89 00:04:47,080 --> 00:04:51,960 そのメソッドをレシーバーに適用します。 Dice に適用します。 90 00:04:52,120 --> 00:04:55,480 すると新しいインスタンスが得られます。 ここに書いておきます。 91 00:04:55,640 --> 00:04:58,120 インスタンスが返ってきます。ダイスです。 92 00:04:58,280 --> 00:05:02,000 そして inst は この新しいインスタンスを指します。 93 00:05:03,000 --> 00:05:05,400 つまり、inst は新しいダイスです。 94 00:05:06,040 --> 00:05:10,680 inst に initialize メッセージを 送って、そしてそれを返します。 95 00:05:10,840 --> 00:05:15,760 この例題はゴチャゴチャとなりがちです。 回りくどいですからね。 96 00:05:15,920 --> 00:05:19,840 ちゃんと理解しているかどうか判るように わざとそうしています。 97 00:05:20,000 --> 00:05:21,920 2 つの事が混ざっています。 98 00:05:22,080 --> 00:05:23,880 1 つは super です。 99 00:05:24,040 --> 00:05:29,040 super という式を含むクラスの スーパークラスを見るということです。 100 00:05:29,200 --> 00:05:31,440 super が指すのはレシーバーです。 101 00:05:31,600 --> 00:05:35,240 2 つ目は、new です。 new はオブジェクトを生成するメソッドです。 102 00:05:35,400 --> 00:05:37,120 この例ではこの 2 つが 組み合わさっていることで 103 00:05:37,280 --> 00:05:40,080 理解するのが難しくなっています。 104 00:05:40,240 --> 00:05:43,520 この授業を復習することをお勧めします。 105 00:05:43,680 --> 00:05:45,640 とても重要な内容だからです。 106 00:05:45,800 --> 00:05:46,920 繰り返しますが 107 00:05:47,080 --> 00:05:50,240 super はメッセージのレシーバーです。 108 00:05:50,400 --> 00:05:53,160 この場合、Dice です。 109 00:05:53,320 --> 00:05:57,560 Dice クラスのスーパークラスから new メソッドを探します。 110 00:05:57,720 --> 00:06:02,320 それをレシーバーであるDice に適用して インスタンスの生成をします。 111 00:06:03,120 --> 00:06:04,280 いいですか? 112 00:06:05,760 --> 00:06:11,080 まとめると、メッセージ送信は レシーバーのクラスからメソッドを探索します。 113 00:06:11,240 --> 00:06:13,080 メッセージ送信のたびに探索を実行します。 114 00:06:13,240 --> 00:06:15,960 Pharo でやることはそれだけです。 簡単ですね。 115 00:06:16,160 --> 00:06:20,400 これで、super はその式を持つクラスの スーパークラスから探索するという 116 00:06:20,560 --> 00:06:22,680 意味だということを理解できたはずです。 117 00:06:22,880 --> 00:06:26,440 そして super はレシーバーであり レシーバーがクラスの場合もあります。 118 00:06:26,880 --> 00:06:30,160 これで終わりではありません。 もう 1 つ問題があります。 119 00:06:30,320 --> 00:06:33,520 Pharo を勉強するぐらいだから 何かに挑戦するのが好きですよね? 120 00:06:33,680 --> 00:06:37,520 さあ、次の問題を考えてみましょう。 121 00:06:37,680 --> 00:06:41,120 メソッドに super class 122 00:06:41,280 --> 00:06:42,880 == self class と書いてあるとします。 123 00:06:43,040 --> 00:06:46,520 この == はどういう意味かというと ポインタが同一かどうかの比較です。 124 00:06:46,680 --> 00:06:49,800 意味としては 125 00:06:49,960 --> 00:06:53,200 この super class で 得られるオブジェクトは 126 00:06:53,360 --> 00:06:56,160 self class で得られるオブジェクトと 同一のものか、ということです。 127 00:06:56,360 --> 00:06:59,760 このメソッドは true か false の どちらかを返します。 128 00:06:59,920 --> 00:07:01,280 では問題です。 129 00:07:01,440 --> 00:07:05,200 A new foo の結果は何でしょう? 130 00:07:05,360 --> 00:07:07,600 A の新しいインスタンスを作って 131 00:07:07,760 --> 00:07:11,360 foo メッセージを送ります。 つまりこのメッセージを評価します。 132 00:07:11,520 --> 00:07:13,600 結果は何でしょう?その理由は? 133 00:07:13,760 --> 00:07:17,120 答えは自分で考えてみてください。 私から正解は教えません。