|
|
連載
改訂版 プロフェッショナルVB.NETプログラミング
Chapter 10 継承とポリモーフィズム
株式会社ピーデー
川俣 晶
2004/06/24 |
|
継承は、VB.NETになって初めて導入された機能である。インターフェイスの機能など、似た機能がVB 6にもなかったわけではないのだが、継承の方が、インターフェイスよりもはるかに多くの機能を持っており、単純に「強化されたインターフェイス」を想像するだけでは、十分に把握しきれないものになるだろう。一度、頭の中を真っ白にして、新しい機能を学ぶ気持ちで本章を読むとよいかもしれない。
また、継承という機能で実現されるポリモーフィズムについても本章では説明している。継承とポリモーフィズムは、クラス・ライブラリなどを活用する場合には欠かせない機能なので、学んでおく価値があるだろう。
継承とは(非常に曖昧で不確かな言い方で説明するなら)あるクラスの機能を、別のクラスで引き継ぐことである。最も簡単な機能の引き継ぎは、あるクラスに含まれるメソッドを、別のメソッドからでも利用可能にすることだろう。
まず、このようなクラスを作ってみた(リスト10-1)。何の変哲もない、1個のメソッドを持つクラスである。
1: Public Class Class1
2: Public Sub Test1()
3: Trace.WriteLine("Test1 called")
4: End Sub
5: End Class
|
|
リスト10-1 1個のメソッドを持つ簡単なクラスを定義したプログラム
|
次に、このクラスを継承するクラスを記述してみた。リスト10-2がそれである。
1: Public Class Class2
2: Inherits Class1
3: Public Sub Test2()
4: Trace.WriteLine("Test2 called")
5: End Sub
6: End Class
|
|
リスト10-2 リスト10-1のクラスを継承するクラス
|
このコードで注目する必要があるのは、2行目のInheritsステートメントである。このステートメントに続いて、継承するクラスの名前を記述してある。これにより、Class2はClass1の機能を継承していることになる。実際に継承できていることを確認するために記述したのが、リスト10-3である。
1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
2: Dim o1 As New Class1()
3: Dim o2 As New Class2()
4: o1.Test1()
5: 'o1.Test2()
6: o2.Test1()
7: o2.Test2()
8: End Sub
|
|
リスト10-3 継承されていることを確認するプログラム
|
これを実行すると以下のようになる。
1: Test1 called
2: Test1 called
3: Test2 called
|
|
リスト10-4 リスト10-3の実行結果
|
コード6行目のo2.Test1()は、Class2のインスタンスであるo2を経由して、Class1のメソッドTest1を呼び出そうとしている。これは、Class2がClass1を継承していることにより、正常に機能する。しかし、5行目のo1.Test2()のように、Class1のインスタンスに対して、Class2のメソッド呼び出しはできない。なぜなら、Class1自身はClass2を継承しているわけではない(Class1には“Inherits Class2”という記述がない)ためである。
なお、Class2にInherits Class1と記述したら、Class1にInherits Class2と記述することはできない。継承は循環できないのである。
ここで、用語についても説明しておこう。Aというクラスを継承したBというクラスがあるとき、AはBのスーパー・クラスであるといい、BはAのサブ・クラスであるという。この場合なら、Class1はClass2のスーパー・クラスであるといい、Class2はClass1のサブ・クラスであるという。
継承の機能を用いれば、既存のクラスを書き換えることなく、容易に機能を追加できるようになる。例えば、基本機能だけを含む再利用可能なクラスを作っておき、継承機能を用いて個々のアプリケーション・ソフトで必要になる独自機能を付け加えていくことが可能になる。
あるクラス内のメソッドから、同じクラス内のメソッドを呼び出すとき、いちいちインスタンスを明示せずとも、メソッドの名前だけで呼び出すことができる。これと同じことは、継承したクラスから継承元のメソッドを呼び出すときにも適用される。これを確かめるためにサンプル・プログラムを記述してみた。まずは継承元のクラスから(リスト10-5)。
1: Public Class Class1
2: Public Sub Test1()
3: Trace.WriteLine("Test1 called")
4: End Sub
5: End Class
|
|
リスト10-5 継承元となるクラスを定義したプログラム
|
このクラスを継承した別のクラスを作成してみた(リスト10-6)。
1: Public Class Class2
2: Inherits Class1
3: Public Sub Test2()
4: Trace.WriteLine("Test2 called")
5: End Sub
6:
7: Public Sub TestCaller()
8: Test1()
9: Test2()
10: End Sub
11: End Class
|
|
リスト10-6 リスト10-5を継承するプログラム
|
10行目のTest2()が、4〜6行目のTest2メソッドを呼び出すことは明らかだろう。だが、9行目のTest1()も、同様にClass1のTest1メソッドを呼び出すことができる。実際に呼び出せていることを、以下のようなコードで確かめてみよう(リスト10-7)。
1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
2: Dim o2 As New Class2()
3: o2.TestCaller()
4: End Sub
|
|
リスト10-7 クラスClass1のメソッドTest1が呼び出されることを確認するプログラム
|
これを実行すると以下のようになる。
1: Test1 called
2: Test2 called
|
|
リスト10-8 リスト10-7の実行結果
|
これはメソッドだけに限られるものではなく、プロパティなどでも同様にインスタンスを明示せずに扱うことができる。
なお、継承元のメソッドは、常に継承先から呼び出し可能というわけではない。この例では、メソッドの宣言に付いたPublicキーワードが、呼び出し可能であることを示している。しかし、ここにPublicではなく、Privateキーワードが付加されている場合は、呼び出すことができない。
業務アプリInsider 記事ランキング
本日
月間