ObjectSquare [1999 年 2 月号]

[Happy Squeaking!!]


2.Squeak演習:クラスの継承関係作成

2.7 superの利用


「論よりコード」で、まず以下のようにEmployeeの giveNameCardを変更してみましょう。

giveNameCard
	Transcript cr; 
	 	    show:  'giving ' , ( super getName ) , ' card'.

実行結果は、以下のように

giving Suzuki card

と、元に戻ってしまいます。

自分自身に対する呼び出しを行う際に、selfの代わりに superを使用することができます。この場合、メッセージの対応するメソッドの検索は、自身の属するクラスを無視して、一つ上のスーパークラスから行われることになります。上記の例では、getNameメソッドが自分のクラスでオーバーライドされているにも関わらず、それが無視されて一つ上のスーパークラスであるHumanからgetNameメソッドが検索され、起動されるのです。

superは、スーパークラスとサブクラスでメソッドの実装の差分を記述する際に有効です。
例として初期化のメソッドinitializeをHumanクラスとEmployeeクラスに追加することにします。

Humanクラスのinitializeでは、自分のクラスで定義されている属性、nameの初期化を行います。

Human クラスの initiallize (initialize-releaseカテゴリ)

initialzie

	name := 'NO NAME'.

Humanのサブクラス、Employeeでは、新たに id、employedDateの属性が加わっているので、その部分の初期化を行うようにします。

Employee クラスの initiallize (initialize-releaseカテゴリ)

initialzie
	id := 0.
	employedDate := Date today.
Date todayは、Dateというクラスにtodayメッセージを送ることで「今日の日付」インスタンスを生成しています。(通常はnewとするところですが、Dateの場合はわかりやすさのためにこういったメソッドが使えます)
SmallTip: Dateは日付を表すクラス。todayメッセージを送ることで、「今日の日付」インスタンスを得ることができる。

このような状態で以下のコードをワークスペースで実行してみます。

| emp |
emp := Employee new.
emp initialize.
emp inspect.

( Smalltalkの書き方に慣れてきた方は以下のように

Employee new initialize inspect.

と短くしていただいてかまいません)。

立ち上がったインスペクタをみてみましょう。

initializeの記述が不十分なEmployeeインスタンス

Employeeのインスタンスにinitializeメッセージを投げた場合、initializeメソッドがオーバーライドされているため、当然、自分のクラスで定義したinitializeが起動されます。しかし、そのinitializeの中ではスーパークラスから定義を継承しているはずのname属性の初期化を行っていないために、nameの値はnilのままになっています。

ひとつの解決策として、Employeeのinitializeメソッドに、nameの初期化部分を書いてしまう方法があります。

Employee クラスの initiallize (initialize-releaseカテゴリ)

initialzie
	name := 'NO NAME'.  "<= 追加部分"
	id := 0.
	employedDate := Date today.

しかしこれでは、前述のselfでの例のように、同じコードが二箇所に分散することになります。

これを防ぐには「自分のinitializeの中でスーパークラスのinitializeを呼び出して、次に残りの処理を行う」とすれば良いことになります。

つまり、

initialzie
	super initialize..  "<=スーパークラスのinitializeを起動"
	id := 0.
	employedDate := Date today.

となります。

このようにEmployeeのメソッドを変更すると、インスペクタの結果は、

super initializeを含むEmployeeのインスタンス

となり、無事に初期化を行わせることができました。

superはサブクラスでメソッドの前処理や後処理を付け加える際に使うことができます。

スーパークラスであるメソッド、operationが定義されているとして、サブクラスでは、

operation
	"前処理の記述"
	*.
	super oeration
	"後処理の記述"

といった具合です。実装コードが継承により再利用できていることが確認できるかと思います。

SmallTip: 自身を表すオブジェクトはselfの他superがある。この場合、メッセージに対応するメソッドの検索は自分のスーパークラスを参照して行われる

© 1999-2001 OGIS-RI Co., Ltd.

Prev.

Index

Next