1 00:00:00,360 --> 00:00:01,800 こんにちは。この講義では 2 00:00:01,960 --> 00:00:06,440 クラスメソッドを本当に理解するための 時間を設けます。 3 00:00:06,600 --> 00:00:08,960 既にカウンターの演習をしましたが 4 00:00:09,120 --> 00:00:12,520 クラスメソッドを使ったはずです。 上手くいきましたね。 5 00:00:12,680 --> 00:00:16,440 今回はじっくり見ていって 一から十まで理解してください。 6 00:00:17,400 --> 00:00:20,800 この講義では、Pharo では クラスメソッドとインスタンスメソッドには 7 00:00:20,960 --> 00:00:24,240 メソッド探索のレベルでは違いはない ということを学びます。 8 00:00:24,400 --> 00:00:27,320 探索アルゴリズムは 1 つしかありません。 9 00:00:27,480 --> 00:00:32,400 仮想機械(VM)で定義されています。 10 00:00:32,560 --> 00:00:37,240 そしてクラスメソッドは一見すると 静的(static)メソッドに似ていますが 11 00:00:37,400 --> 00:00:40,320 実際には違うということが解るでしょう。 12 00:00:40,480 --> 00:00:43,200 実際、クラスメソッドは動的結合されます。 13 00:00:43,360 --> 00:00:45,600 クラスメソッドは実行時に探索されます。 14 00:00:45,760 --> 00:00:50,080 一方、Java では静的メソッドは 動的に探索されません。 15 00:00:50,240 --> 00:00:51,720 では、どうなっているのか見てみましょう。 16 00:00:51,880 --> 00:00:54,680 実際、今までに探索アルゴリズムは 17 00:00:54,840 --> 00:00:59,600 レシーバーのクラスから開始する ということは、わかっていますね。 18 00:00:59,760 --> 00:01:02,600 もし該当するメソッドがあれば 19 00:01:02,760 --> 00:01:06,000 それが返され、なければ スーパークラスを辿っていきます。 20 00:01:06,160 --> 00:01:08,560 図で見てみると 21 00:01:08,720 --> 00:01:11,720 Counter クラスの例では 22 00:01:11,880 --> 00:01:14,880 increment メッセージを送ると 何が起こるでしょう? 23 00:01:15,040 --> 00:01:20,160 まずはCounter クラスを見て 24 00:01:20,320 --> 00:01:22,040 increment がここで定義されてるか 見てみます。 25 00:01:22,200 --> 00:01:26,120 階層のより上位で定義されたメソッドなら 26 00:01:26,280 --> 00:01:28,120 上位へ辿っていきます。 27 00:01:28,280 --> 00:01:31,760 このメカニズムが 実際に Pharo で 使われているもので、他には探索はありません。 28 00:01:31,920 --> 00:01:35,280 インスタンス側でもクラス側でも これが使われています。 29 00:01:36,680 --> 00:01:41,640 Counter クラスの演習では withValue: メッセージを 30 00:01:41,840 --> 00:01:44,320 Counter クラスに送って 31 00:01:44,480 --> 00:01:46,480 インスタンスを作りました。 何が起こっているのでしょう? 32 00:01:46,640 --> 00:01:50,960 Counter クラスは Counter class と呼ばれるクラスのインスタンスです。 33 00:01:51,120 --> 00:01:55,400 そして探索します。 今までと同じ方法で探索します。 34 00:01:55,560 --> 00:01:58,600 レシーバーのクラスを見ます。 レシーバーは Counter なので 35 00:01:58,760 --> 00:02:02,920 Counter class を見ます。 するとwithValue: メソッドが見つかります。 36 00:02:03,080 --> 00:02:05,960 それをレシーバーに適用して 37 00:02:06,120 --> 00:02:08,680 新しいインスタンスを返します。 38 00:02:08,840 --> 00:02:14,760 つまり、Counter クラスのインスタンスに メッセージを送るのと 39 00:02:14,920 --> 00:02:16,960 全く同じプロセスを辿ります。 40 00:02:18,080 --> 00:02:22,560 では、Pharo ではクラスとは何なのでしょう? クラスはインスタンスです。 41 00:02:22,760 --> 00:02:26,480 クラスは他と同じようなオブジェクトです。 Pharo にはオブジェクトしかありません。 42 00:02:26,640 --> 00:02:30,040 クラスはメタクラスと呼ばれる 別のクラスのインスタンスです。 43 00:02:30,200 --> 00:02:34,000 単に区別すれば良いだけです。 メタクラスは単にクラスです。 44 00:02:34,160 --> 00:02:36,080 そのインスタンスがクラスというだけで。 45 00:02:36,880 --> 00:02:40,680 違いは、インスタンスが 末端のインスタンスなのかクラスなのかです。 46 00:02:40,840 --> 00:02:44,680 次にのポイントは Counter クラスは 47 00:02:44,840 --> 00:02:49,040 Counter class クラスの 唯一のインスタンスです。 48 00:02:50,160 --> 00:02:54,640 この Counter class は自動的に作られます。 49 00:02:54,800 --> 00:02:58,040 Counter クラスを定義した時に システムが自動的に 50 00:02:58,200 --> 00:03:01,960 Counter class クラスを作ります。 51 00:03:02,120 --> 00:03:06,040 クラスを 1 つ作ったつもりでしょうが 実際には 2 つ作っていたのです。 52 00:03:06,200 --> 00:03:09,640 Pharo では XXX クラスのクラスは 53 00:03:09,800 --> 00:03:13,680 XXX class と呼ばれることを 覚えておいてください。 54 00:03:13,840 --> 00:03:18,120 ここに Counter がありますが Counter のクラスは 55 00:03:18,280 --> 00:03:22,080 Counter class です。 系統的ですね。 56 00:03:23,600 --> 00:03:26,680 実際のところ 57 00:03:26,840 --> 00:03:30,920 今まで説明なしでやっていたのですが 58 00:03:31,080 --> 00:03:33,800 ブラウザで Counter クラスを見ている時は 59 00:03:33,960 --> 00:03:36,560 ブラウザ上のコードは Counter classの 60 00:03:36,720 --> 00:03:40,240 インスタンスで実行されます。 61 00:03:40,400 --> 00:03:42,000 つまり increment は 62 00:03:42,160 --> 00:03:45,840 Counter のインスタンス上で実行されますが 63 00:03:47,440 --> 00:03:52,280 クラスボタンを押して クラスメソッドを定義する時は 64 00:03:52,440 --> 00:03:56,800 この Counter class のインスタンス上で 実行されるコードを表示します。 65 00:03:58,720 --> 00:04:03,000 実際、見てみると increment メッセージを 66 00:04:03,160 --> 00:04:07,680 Counter のインスタンスに送ると Counter クラスを見ます。 67 00:04:07,840 --> 00:04:10,240 見てください。 このメソッドが実行されます。 68 00:04:10,400 --> 00:04:15,360 Counter クラスに withValue: メッセージを送ると 69 00:04:15,520 --> 00:04:18,800 どこを見るでしょう?そのクラスです。 このリンクを辿って 70 00:04:18,960 --> 00:04:21,040 メソッドがここにあります。 71 00:04:22,320 --> 00:04:24,000 まとめると 72 00:04:24,240 --> 00:04:26,320 Pharo では、クラスはオブジェクトです。 73 00:04:26,480 --> 00:04:27,960 クラスはメッセージを 受け取ることができます。 74 00:04:28,120 --> 00:04:30,680 構文を勉強した時に 75 00:04:30,840 --> 00:04:32,720 Date today について説明しました。 76 00:04:32,880 --> 00:04:37,680 どういうことかというと それはクラスへ送るメッセージです。 77 00:04:37,840 --> 00:04:40,040 構文的に異なる要素はありません。 78 00:04:40,200 --> 00:04:44,040 インスタンスへのメッセージ送信と 構文は全く同じです。 79 00:04:44,200 --> 00:04:48,640 さらに、この講義で、メソッド探索は 1 種類しかないことを説明しました。 80 00:04:48,800 --> 00:04:51,760 クラスメソッドは インスタンスメソッドと同様に 81 00:04:51,920 --> 00:04:54,520 動的に探索されます。 どこを探索するかというと 82 00:04:54,680 --> 00:04:56,560 レシーバーのクラスです。 83 00:04:56,720 --> 00:04:59,520 インスタンスの場合には そのクラスを探します。 84 00:04:59,680 --> 00:05:01,800 クラスインスタンスの場合には 例えば Counter クラスの場合には 85 00:05:01,960 --> 00:05:05,880 メタクラスを探します。 Counter class と呼ばれるクラスです。 86 00:05:06,040 --> 00:05:10,520 つまりクラスは、メタクラスという 別のクラスのインスタンスです。 87 00:05:10,680 --> 00:05:13,560 そして同じメソッド探索が行われます。 88 00:05:13,720 --> 00:05:17,480 これについては最終週の講義 89 00:05:17,640 --> 00:05:20,640 Understanding Metaclasses で またやります。 90 00:05:20,800 --> 00:05:24,040 Pharo の蓋を開けてみて 91 00:05:24,200 --> 00:05:27,080 どうやって動いているのか その完全に統一されたやり方を説明します。