﻿1
00:00:00,480 --> 00:00:05,200
こんにちは。今日はプログラムの

2
00:00:05,360 --> 00:00:07,720
とても微妙なところを
分析してみましょう。

3
00:00:07,880 --> 00:00:11,640
まず最初に、ダイスプログラムを
振り返ってみましょう。

4
00:00:11,800 --> 00:00:16,520
覚えていると思いますが
この演習ではダイスを定義して

5
00:00:16,680 --> 00:00:20,840
色々な面の数をもつダイスの
インスタンスを定義しました。

6
00:00:21,000 --> 00:00:24,920
ダイスハンドルというクラスを
定義しました。

7
00:00:25,360 --> 00:00:29,440
そして DiceHandle クラスに

8
00:00:29,600 --> 00:00:31,320
+ メソッドを実装して
ダイスハンドル同士を足し合わせて

9
00:00:31,480 --> 00:00:34,840
新しいダイスハンドルを
作れるようにしました。

10
00:00:35,000 --> 00:00:37,600
これがこのクラスのコードです。

11
00:00:37,760 --> 00:00:40,680
DiceHandle new があります。

12
00:00:40,840 --> 00:00:42,920
新しいダイスハンドルを
作って

13
00:00:43,080 --> 00:00:46,680
レシーバーのダイスと

14
00:00:46,840 --> 00:00:48,200
もう1方のダイスを加えて

15
00:00:48,360 --> 00:00:52,040
メソッドの最後でこのハンドルを
返します。いいですね？

16
00:00:53,280 --> 00:00:57,960
今回は、この + メソッドで

17
00:00:58,120 --> 00:01:02,200
DiceHandle new と書く場合と
self class new と書く場合の

18
00:01:02,360 --> 00:01:04,840
違いを見ていきます。
そしてこれらのうち

19
00:01:05,000 --> 00:01:07,560
どちらが優れているか
その理由がわかるでしょう。

20
00:01:08,160 --> 00:01:09,840
ここにそのプログラムがあります。

21
00:01:10,200 --> 00:01:15,440
もし DiceHandle のサブクラスとして
MemoDiceHandle を作って

22
00:01:16,080 --> 00:01:20,720
DiceHandle クラスから継承した
+ メソッドで MemoDiceHandle 同士を

23
00:01:20,880 --> 00:01:24,280
足し合わせたい場合には

24
00:01:24,440 --> 00:01:28,600
結果は DiceHandle クラスの
インスタンスになります。

25
00:01:28,760 --> 00:01:30,880
MemoDiceHandle クラスの
インスタンスではありません。

26
00:01:31,040 --> 00:01:33,840
これは問題です。
足し合わせたら

27
00:01:34,000 --> 00:01:36,720
同じ種類のものを
返してほしいからです。

28
00:01:36,880 --> 00:01:38,400
どうしたら良いでしょう？

29
00:01:38,560 --> 00:01:40,080
1 つ目の解決策は

30
00:01:40,480 --> 00:01:42,960
DiceHandle クラスの

31
00:01:43,120 --> 00:01:46,080
+ メソッドの実装を変えます。

32
00:01:46,560 --> 00:01:48,080
+ メソッドです。いいですね？

33
00:01:48,240 --> 00:01:53,280
そしてこのメソッドを追加します。
self handleClass

34
00:01:53,440 --> 00:01:58,320
インスタンス変数ではなく

35
00:01:58,480 --> 00:02:02,160
handleClass というメソッドを
使います。
that I call handleClass.

36
00:02:02,320 --> 00:02:05,160
DiceHandle では
DiceHandle クラスを返します。

37
00:02:05,320 --> 00:02:09,800
サブクラスのMemoDiceHandle クラスでは
MemoDiceHandle クラスを返します。

38
00:02:10,160 --> 00:02:14,480
つまり、単純に handleClass メソッドを
再定義することで

39
00:02:14,640 --> 00:02:19,720
正しいクラスのインスタンスを
得ることができます。

40
00:02:21,120 --> 00:02:25,280
同じコードを
MemoDicehandle で実行したら、

41
00:02:25,440 --> 00:02:30,520
MemoDiceHandle クラスの
インスタンスが得られます。

42
00:02:30,680 --> 00:02:33,680
MemoDiceHandle クラスの
handleClass メソッドを

43
00:02:33,840 --> 00:02:38,280
再定義したからです。
サブクラスのインスタンスが得られます。

44
00:02:38,440 --> 00:02:42,160
これで目的は達成できます。

45
00:02:42,760 --> 00:02:46,200
問題は

46
00:02:46,360 --> 00:02:51,680
DiceHandle のサブクラスを
定義するたびに

47
00:02:51,840 --> 00:02:54,240
handleClass メソッドを
再定義しなければならないことです。

48
00:02:54,400 --> 00:02:59,600
再定義しなければ、 + メソッドは
正しいクラスのインスタンスを返しません。

49
00:02:59,760 --> 00:03:03,720
めんどくさいですね。
常に再定義しなければなりません。

50
00:03:03,880 --> 00:03:05,080
もう少し良い方法があります。

51
00:03:05,600 --> 00:03:09,000
2 つ目の解決策は

52
00:03:09,160 --> 00:03:13,200
DiceHandle クラスの + メソッドで

53
00:03:13,360 --> 00:03:16,160
self class new.
とします。

54
00:03:17,000 --> 00:03:20,680
レシーバーにクラスを尋ねて

55
00:03:20,840 --> 00:03:22,640
インスタンスを得ます。

56
00:03:22,800 --> 00:03:27,240
self class は常にレシーバーの
クラスを答えるので

57
00:03:27,400 --> 00:03:29,360
もしレシーバーがサブクラスならば

58
00:03:29,520 --> 00:03:33,520
正しくサブクラスを答えます。
例えば、MemoDiceHandle クラスです。

59
00:03:33,680 --> 00:03:37,840
レシーバーと同じ種類の
インスタンスが得られます。

60
00:03:38,520 --> 00:03:40,480
まとめると

61
00:03:40,640 --> 00:03:42,400
見ての通り

62
00:03:42,800 --> 00:03:47,040
ダイスハンドルに
+ メッセージを送ると

63
00:03:47,200 --> 00:03:52,080
クラス名を書いた場合には

64
00:03:52,240 --> 00:03:56,760
サブクラスのインスタンスを得る上で
邪魔になります。

65
00:03:56,920 --> 00:04:01,400
self class new とすることで
レシーバーのインスタンスが得られます。

66
00:04:01,560 --> 00:04:03,280
サブクラスの場合も含めて。

67
00:04:03,440 --> 00:04:06,920
つまり、self class new とした方が
ずっと良いです。

68
00:04:07,080 --> 00:04:09,480
レシーバーの種類に応じて

69
00:04:10,120 --> 00:04:14,720
そのクラスのインスタンスを
直接得ることができます。
