﻿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
答えは自分で考えてみてください。
私から正解は教えません。