オブジェクト指向でプログラミングをすると、あるクラスを他のクラスから再利用する場面によく出くわします。継承とコンポジションは、双方ともクラス同士の関係性を築くものですが、意味は異なります。継承の関係を持たせるか、あるいはコンポジションの関係を持たせるかは、プログラマー次第ではありますが、その違いははっきりと認識しておかなければなりません。
ここで、あるクラスが他のクラスの"一種である(is a kind of)" ときは継承を、"持っている(has)" ときはコンポジションの関係を持たせればよいということになります。例えば、シャツとボタンの関係は、コンポジション(シャツはボタンを持ち合わせる)ということになりますが、シャツとTシャツはそのような関係にはなりません。このようなとき、Tシャツはシャツの一種であるという認識が必要です。
あらためて、「全体-部分」クラス同士がこのような関係を持つことを、コンポジション(集約)といいます。実はこの考え方、普段の私たちの身の回りでは、ごくごく当たり前のように、使用されているのです。
例えば、皆さんが今使っているパソコンが良い例です。ディスプレイ、キーボード、マウスなどは、パソコンの部品、即ち、パソコンとコンポジションの関係にあるといえます。このように、あるクラスとその中で部品化されたクラスというのがコンポジションということになります。
「構造体のメンバ変数に構造体を指定する」これをクラスに当てはめて考えると、コンポジションの関係を持たせることができます。ようは、あるクラスのメンバ変数として他のクラスを指定しまえばいいわけです。
'部品となるクラスを定義 Class CParts ... End Class '親クラスを定義 Class CParent objParts1 As CParts objParts2 As CParts ... End Class
コンポジションの関係を持つ部品側のクラスも、当然のように初期化&終了処理が呼び出されることになります。通常であれば、暗黙的に下のような順序でコンストラクタ/デストラクタが呼び出されます。
コンストラクタとは全くの逆順序でデストラクタが呼ばれるのは、注目したいところですね。これは継承の際も同様のことが言えます。
ここで注意点が1つ。親クラスを生成したときに暗黙的に呼び出される部品クラスのコンストラクタは、引数を持たないものだけになります。引数有りコンストラクタを有する部品クラスが存在するときは、親クラスのコンストラクタ内で任意にその部品クラスのコンストラクタを呼び出してやる必要があります。
下の例では、引数有りコンストラクタを明示的に呼び出しています。
#N88BASIC Class CParts1 Public Sub CParts1() Print "CParts1のコンストラクタ(引数を持たない)。" End Sub Sub ~CParts1() Print "CParts1のデストラクタ。" End Sub End Class Class CParts2 Public Sub CParts2(a As Long) Print "CParts2のコンストラクタ(引数を持つ)。引数の値は、";a End Sub Sub ~CParts2() Print "CParts2のデストラクタ。" End Sub End Class Class CParent obj1 As CParts1 obj2 As CParts2 Public Sub CParent() '引数有りコンストラクタは明示的に呼び出す obj2.CParts2(10) Print "親クラスのコンストラクタ" End Sub Sub ~CParent() Print "親クラスのデストラクタ" End Sub End Class Dim obj As CParent
↑実行結果
講座インデックスへ戻る | ©2005 Discoversoft |