![]() |
[1999 年 2 月号] |
[Happy Squeaking!!]
1.継承
1.2 クラスの継承
「分類するためのもの」としてのクラスは、分類のための指定情報を個々に持っていたのでは効率の悪いことになります。
「柴犬」というクラスを考えた場合に、インスタンスの定義情報として、
といったものをすべて待たせることもできますが、「犬」や「哺乳類」といったより上位の分類を意味するクラスでも同じような定義が存在するため、情報としては冗長になってしまいます。
一方で、
「哺乳類」
「犬」
「柴犬」
として、上位クラスで規定されているインスタンス定義情報が下位クラスでそのまま暗に含まれることにすれば、情報の冗長化を防ぐことができます。
このように、上位のクラスが持つインタンスについての定義情報を、その下位のクラスがそのまま引き継いで自分のインスタンス定義情報として使えることを、オブジェクト指向の世界では「(上位のクラスからの定義情報を)継承する」という言葉によって表します。
クラスの上下関係を定めることにより継承されるものは、属性、操作の定義にとどまりません。クラスをサポートするオブジェクト指向言語では、通常操作の実装はクラスが保持しており、インスタンスは、センダからのメッセージが来た場合に、自分の属するクラスに存在する操作の実装(メソッド)を起動します。この操作の実装も下位のクラスは継承して手に入れることになります。
複数のインスタンスの持つ共通性は、「クラス」という形でまとめあげられましたが、各クラスが持つインスタンス定義情報の共通性は、「クラス間の継承」という階層化の仕組みによりまとめられていくのです。
継承を使ったクラス定義から、インスタンスが生成されるイメージは以下のようになります。(今度は会社員の例を使っています)
インスタンス生成のイメージ
インスタンスは、上位クラス群での定義情報をすべて含んだ形で生成されます。
特定のクラスから見て上位のクラスは通常「スーパークラス」、下位のクラスは「サブクラス」というふうに呼ばれます。(これは相対的な概念です)。
サブクラスで生成されたインスタンスは、あたかも自分のクラスで属性、操作の全ての定義情報があったかのような構成になるのですが、実際の定義は部分的にスーパークラスに存在することになります。
サブクラスのインスタンスにメッセージが来た際には、インスタンスは、対応する操作の実装(メソッド)を、自分のクラスだけでなく、スーパークラスからも参照して起動します。この場合には、操作の実装が継承されて起動されることになります。
操作においては、サブクラスがスーパークラスと同じ名前の操作をわざと再定義することもできます。サブクラスのインスタンスは自分のクラスの方にある操作を優先して起動するので、スーパークラスは操作の振る舞いの仕方を書き換えることになります。これは通常オーバーライド(上書き)と呼ばれています。
継承によって「属性」「操作」の多くの情報のコピーが様々なクラスに散在することが避けられるようになります。開発者にとっては、属性や、操作は、上位クラスからの変更、および追加したい部分だけを下位クラスで再び書き下せばよくなるので、これを「差分プログラミング」と呼ぶ場合もあります。
クラス群を上手に階層化することによって、概念上の区分がきちんと為され、かつ冗長なコードの存在しないシステムが作られていきます。
一方で、操作の実装の再利用だけにとらわれ、概念上の上下関係を無視すると、継承の誤った使用により保守性を低めることがあるので注意が必要です。(これについてはより説明の進んだ時点でふりかえります)。
© 1999-2001 OGIS-RI Co., Ltd. |
|