WEBVTT

00:00:08.000 --> 00:00:12.320 align:middle
やあ、みなさん、このビデオでは
クラスの上級編をお見せします。

00:00:13.720 --> 00:00:15.320 align:middle
3 つのことをします。

00:00:15.520 --> 00:00:20.760 align:middle
1 つ目は、クラスやそのサブクラスの
インスタンス間での状態の共有です。

00:00:22.280 --> 00:00:27.240 align:middle
2 つ目は、クラス自身に変数を
持たせる方法です。

00:00:28.600 --> 00:00:30.960 align:middle
3 つ目は、クラスの初期化です。

00:00:32.760 --> 00:00:36.160 align:middle
まず最初に、インスタンス間で
状態を共有する方法です。

00:00:37.560 --> 00:00:41.640 align:middle
ここにクラスと
いくつかのインスタンスがあります。

00:00:41.920 --> 00:00:47.200 align:middle
状態を共有するためには、これらの
インスタンスに共通するオブジェクトが必要です。

00:00:47.720 --> 00:00:53.920 align:middle
Java では、「静的(static)」な
インスタンス変数を使います。

00:00:55.160 --> 00:00:58.240 align:middle
静的な変数の値は

00:00:58.680 --> 00:01:00.720 align:middle
全てのインスタンスで同じです。

00:01:01.640 --> 00:01:04.640 align:middle
Pharo ではクラス変数を使います。

00:01:06.200 --> 00:01:11.120 align:middle
これはクラスを作るときの
見慣れた表現式ですね。

00:01:11.480 --> 00:01:15.640 align:middle
ここでは Color クラスを作っています。
Object のサブクラスです。

00:01:15.800 --> 00:01:21.600 align:middle
まず、インスタンス変数を列挙していて
その次の行を見ると

00:01:21.920 --> 00:01:25.480 align:middle
Color クラスのクラス変数を
列挙しています。

00:01:26.640 --> 00:01:32.200 align:middle
Color クラスには少なくとも2つの変数があります。
ColorRegistry と ComponentMask です。

00:01:32.720 --> 00:01:34.440 align:middle
クラス変数の値は

00:01:34.680 --> 00:01:39.400 align:middle
そのクラスとサブクラスの
全てのインスタンスに共有されます。

00:01:40.480 --> 00:01:46.600 align:middle
これらの変数はインスタンスメソッドからも
クラスメソッドからもアクセス可能です。

00:01:47.480 --> 00:01:49.920 align:middle
クラス変数は大文字で始まります。

00:01:50.520 --> 00:01:52.840 align:middle
例題に戻りましょう。

00:01:53.320 --> 00:01:55.600 align:middle
Color クラスは

00:01:55.920 --> 00:01:59.520 align:middle
メタクラス Color class の
インスタンスです。

00:02:01.160 --> 00:02:06.760 align:middle
Color クラスでは 2 つのインスタンス変数
が定義されています。grb と alpha です。

00:02:06.960 --> 00:02:09.720 align:middle
これらのインスタンス変数はプライベートです。

00:02:10.760 --> 00:02:16.240 align:middle
つまり、Color クラスのメソッドからしか
アクセスできません。

00:02:18.440 --> 00:02:24.560 align:middle
ColorRegistry も定義されています。
これは下線が引かれ大文字になっています。

00:02:25.240 --> 00:02:28.360 align:middle
つまりこの変数は共有されている
ということを示しています。

00:02:29.480 --> 00:02:33.080 align:middle
この変数はクラス変数で

00:02:33.600 --> 00:02:39.640 align:middle
Color クラスや Color class クラスの
メソッドからアクセス可能です。

00:02:40.240 --> 00:02:43.600 align:middle
この変数を使った例があります。

00:02:44.000 --> 00:02:48.520 align:middle
Color クラスの privateBlue という
インスタンスメソッドでは

00:02:48.840 --> 00:02:54.320 align:middle
クラス変数を名前でアクセスしています。

00:02:55.360 --> 00:02:59.280 align:middle
同様に、この変数に値を代入するには

00:02:59.640 --> 00:03:03.560 align:middle
:= を使います。他の変数と同じです。

00:03:03.880 --> 00:03:06.920 align:middle
インスタンス側でもクラス側でも可能です。

00:03:07.400 --> 00:03:08.480 align:middle
よくある使い方は

00:03:09.000 --> 00:03:14.720 align:middle
クラス変数の値が

00:03:15.800 --> 00:03:17.600 align:middle
インスタンスメソッドで読まれて

00:03:17.800 --> 00:03:21.680 align:middle
クラスメソッドで書き込みます。

00:03:22.080 --> 00:03:25.960 align:middle
よく使われるやり方ですが
そうしなければならないというわけではありません。

00:03:28.040 --> 00:03:31.440 align:middle
では、クラスのインスタンス変数を
見てみましょう。

00:03:33.320 --> 00:03:34.920 align:middle
これはこれで別物です。

00:03:35.200 --> 00:03:38.360 align:middle
クラスはオブジェクトです。
他のオブジェクトと同様に。

00:03:38.520 --> 00:03:41.600 align:middle
他のオブジェクトと同様に
クラスもインスタンス変数を持つことができます。

00:03:42.440 --> 00:03:48.560 align:middle
メタクラスがクラスを定義して
インスタンス変数を列挙します。

00:03:48.760 --> 00:03:52.800 align:middle
それらのインスタンス変数はそのシングルトンである
クラスからのみアクセスできます。

00:03:53.440 --> 00:03:57.840 align:middle
クラス側にインスタンス変数を定義するには

00:03:58.480 --> 00:04:02.000 align:middle
コードブラウザの
「class」ボタンをクリックします。

00:04:02.160 --> 00:04:04.400 align:middle
するとこの表現式が出てきます。

00:04:04.560 --> 00:04:07.840 align:middle
今、RPackageSet クラスを
ブラウズしていますが

00:04:08.280 --> 00:04:13.400 align:middle
このクラスのメタクラスは
cachePackages という名前の変数を定義しています。

00:04:15.440 --> 00:04:19.240 align:middle
こういった変数はクラスメソッドからのみ
アクセスすることができます。

00:04:20.280 --> 00:04:24.920 align:middle
そして必ず小文字で始まります。

00:04:25.800 --> 00:04:27.240 align:middle
例題があります。

00:04:27.960 --> 00:04:32.960 align:middle
変数 cachePackages は
メタクラス RPackageSet class で

00:04:35.280 --> 00:04:36.720 align:middle
定義されています。
つまり

00:04:37.520 --> 00:04:42.480 align:middle
RPackageSet クラスはメタクラス
RPackageSet class のインスタンスですが

00:04:42.640 --> 00:04:45.560 align:middle
この変数に関連付けられた値を持っています。

00:04:46.840 --> 00:04:48.080 align:middle
同様に

00:04:49.280 --> 00:04:53.760 align:middle
RPackageSet クラスの全てのサブクラスは

00:04:54.000 --> 00:04:58.600 align:middle
この変数の
それぞれの異なる値を持っています。

00:04:58.760 --> 00:05:00.400 align:middle
共有されていません。

00:05:00.600 --> 00:05:04.920 align:middle
RPackageSet クラスやそのサブクラスは

00:05:05.080 --> 00:05:07.600 align:middle
この変数にそれぞれの値を持っています。

00:05:08.040 --> 00:05:14.040 align:middle
クラス変数とクラス側のインスタンス変数は
別のものです。

00:05:14.200 --> 00:05:17.960 align:middle
シングルトンパターンを使って説明します。

00:05:18.160 --> 00:05:23.240 align:middle
シングルトンパターンの目的はクラスのインスタンスが
1つだけであることを保証することです。

00:05:24.800 --> 00:05:29.720 align:middle
このパターンを実装する方法の 1 つは
変数にインスタンスを格納して

00:05:30.920 --> 00:05:36.160 align:middle
そのインスタンスへのアクセスを提供して
インスタンス生成を無効化することです。

00:05:36.920 --> 00:05:39.920 align:middle
WebServer でそれをやってみます。

00:05:41.040 --> 00:05:45.440 align:middle
ここでクラス側の
インスタンス変数を使います。

00:05:46.760 --> 00:05:48.960 align:middle
名前は小文字になっています。

00:05:49.120 --> 00:05:53.200 align:middle
この変数はメタクラスの定義で
宣言されています。

00:05:53.760 --> 00:05:56.920 align:middle
そして new メソッドの実行を
無効化しています。

00:05:57.200 --> 00:06:02.040 align:middle
WebServer クラスに新しいインスタンスを
作るようにメッセージを送ることはできません。

00:06:02.240 --> 00:06:05.200 align:middle
uniqueInstance を経由するように
強制されています。

00:06:05.360 --> 00:06:10.640 align:middle
変数の値が nil でなければ
その値が返されて

00:06:11.200 --> 00:06:15.440 align:middle
nil であれば super new を使って
その変数にインスタンスを与えます。

00:06:15.600 --> 00:06:18.840 align:middle
WebServer クラスの
新しいインスタンスを生成して

00:06:19.000 --> 00:06:21.960 align:middle
変数 uniqueInstance に格納します。

00:06:22.560 --> 00:06:27.760 align:middle
実際にクラスインスタンス変数を使うと

00:06:28.400 --> 00:06:30.480 align:middle
次のような結果になります。

00:06:31.240 --> 00:06:34.000 align:middle
WebServer クラスの各サブクラス毎に

00:06:34.520 --> 00:06:36.640 align:middle
それぞれ異なるインスタンスが

00:06:37.240 --> 00:06:39.640 align:middle
uniqueInstance に格納されます。

00:06:40.120 --> 00:06:43.040 align:middle
つまり、WebServer クラスに
サブクラスが 3 つあれば

00:06:43.200 --> 00:06:47.480 align:middle
変数 uniqueInstance には
合計 4 つの値があることになります。

00:06:47.640 --> 00:06:50.600 align:middle
WebServer クラスに 1 つと
各サブクラスに 1 つずつです。

00:06:51.320 --> 00:06:54.600 align:middle
クラス変数を使うと

00:06:55.160 --> 00:07:00.000 align:middle
このクラスのインスタンス側を編集して

00:07:00.200 --> 00:07:04.480 align:middle
UniqueInstance とします。
U は大文字です。

00:07:06.720 --> 00:07:11.920 align:middle
先ほどと同様に new を無効化して
UniqueInstance を実装します。

00:07:12.080 --> 00:07:16.200 align:middle
違いは U が大文字だということです。

00:07:18.080 --> 00:07:21.040 align:middle
クラス変数を使った結果

00:07:22.120 --> 00:07:25.040 align:middle
このクラス階層で唯一のシングルトンを
持つようになります。

00:07:25.240 --> 00:07:27.520 align:middle
WebServer クラスに
サブクラスが 3 つあるとすると

00:07:27.680 --> 00:07:32.080 align:middle
WebServer とその 3 つのサブクラスが
同じシングルトンを共有することになります。

00:07:32.240 --> 00:07:35.680 align:middle
したがって全体で 1 つの
インスタンスを持つことになります。

00:07:36.640 --> 00:07:38.680 align:middle
では、クラスの初期化についてです。

00:07:38.920 --> 00:07:43.720 align:middle
クラスやインスタンスの間で共有される
変数を持つことができますが

00:07:43.920 --> 00:07:46.960 align:middle
いずれかの時点で
値を与えてあげる必要があります。

00:07:47.800 --> 00:07:50.400 align:middle
クラスを初期化する時です。

00:07:50.560 --> 00:07:55.160 align:middle
オブジェクトは initialize メッセージが
送られた時に初期化されます。

00:07:55.320 --> 00:07:59.120 align:middle
同様にクラスへ initialize メッセージを
送ることができます。

00:07:59.320 --> 00:08:04.240 align:middle
initialize メソッドのコードで
どのようにして変数を初期化するかを決めます。

00:08:05.840 --> 00:08:09.000 align:middle
Color クラスを初期化したい場合は

00:08:09.320 --> 00:08:11.840 align:middle
Color クラスに
initialize メッセージを送ります。

00:08:12.680 --> 00:08:16.840 align:middle
典型的にはバージョン管理システムが

00:08:17.160 --> 00:08:19.040 align:middle
システムにクラスをロードした時に

00:08:19.280 --> 00:08:22.520 align:middle
initialize メッセージが送られます。

00:08:22.880 --> 00:08:26.560 align:middle
これは自動的に行われます。
ロードされたクラスそれぞれに

00:08:26.920 --> 00:08:28.960 align:middle
手動でメッセージを送る必要はありません。

00:08:29.120 --> 00:08:31.120 align:middle
しかし、クラスを実装する時に

00:08:31.320 --> 00:08:35.000 align:middle
新しいクラスを式で定義した時には

00:08:35.400 --> 00:08:37.760 align:middle
initialize メッセージを手動で
送る必要があります。

00:08:38.640 --> 00:08:41.280 align:middle
ここに Color クラスの例があります。

00:08:41.480 --> 00:08:44.360 align:middle
メタクラス側を見ています。

00:08:44.680 --> 00:08:49.000 align:middle
いくつかのクラス変数や

00:08:50.320 --> 00:08:53.000 align:middle
クラス側のインスタンス変数を
初期化しています。

00:08:53.240 --> 00:08:55.960 align:middle
ここには両方のタイプの変数があります。

00:08:57.800 --> 00:08:59.680 align:middle
initialize メソッドでは

00:08:59.880 --> 00:09:03.360 align:middle
クラス側では super initialize は
使いません。

00:09:03.560 --> 00:09:07.880 align:middle
インスタンス側で
initialize メソッドを追加する場合には

00:09:08.080 --> 00:09:10.920 align:middle
super initialize を使って系統的に

00:09:11.080 --> 00:09:15.320 align:middle
新しく作られたオブジェクトの
全てのインスタンス変数を初期化します。

00:09:15.520 --> 00:09:16.760 align:middle
しかしクラスの場合には

00:09:16.920 --> 00:09:22.000 align:middle
initialize メッセージが送られた時点で
既にクラスやスーパークラスは存在しているので

00:09:22.160 --> 00:09:25.920 align:middle
クラス側のinitialize メソッドでは
super initialize はしません。

00:09:26.120 --> 00:09:29.760 align:middle
さもないと
クラスを何度も初期化してしまいます。

00:09:30.160 --> 00:09:31.680 align:middle
覚えておくべきポイントです。

00:09:31.880 --> 00:09:35.640 align:middle
状態を共有するためにはクラス変数を使います。

00:09:37.200 --> 00:09:41.000 align:middle
クラスはオブジェクトで
それぞれの変数を持つことができます。

00:09:41.160 --> 00:09:44.320 align:middle
クラス側にもインスタンス変数があります。

00:09:45.000 --> 00:09:48.680 align:middle
クラスを初期化するためには
initialize メッセージを送って

00:09:48.840 --> 00:09:52.200 align:middle
クラス側の initialize メソッドを
適用します。

