|
|
連載
プロフェッショナルVB.NETプログラミング
―― VB 6プログラマーのためのVB.NET入門 ――
最終回 残されたいくつかのトピック(その3)
(株)ピーデー
川俣 晶
2003/01/18
|
オーバーロード
VB 6(Visual Basic 6.0)では、同じ名前のメソッドを同じコンテキスト内で複数記述するとエラーが起きた。以下はVB 6でエラーになるサンプル・プログラムである。引数の型や数が異なるTwoTimesというメソッドが3つ定義されているが、同じフォーム・モジュール中に同じ名前のメソッドが複数あるとエラーになる。
1: Private Sub TwoTimes(ByVal n As Integer)
2: Debug.Print n * 2
3: End Sub
4:
5: Private Sub TwoTimes(ByVal n1 As Integer, ByVal n2 As Integer)
6: Debug.Print (n1 + n2) * 2
7: End Sub
8:
9: Private Sub TwoTimes(ByVal s As String)
10: Debug.Print s & s
11: End Sub
12:
13: Private Sub Form_Load()
14: TwoTimes 123
15: TwoTimes 123, 456
16: TwoTimes "123"
17: End Sub
|
|
引数の型や数が異なる同名のメソッドを定義したVB 6のサンプル・プログラム1(コンパイル・エラーとなる) |
しかし、これをそのままVB.NET(Visual Basic .NET)用に書き換えると、これは動作する。
1: Private Sub TwoTimes(ByVal n As Integer)
2: Trace.WriteLine(n * 2)
3: End Sub
4:
5: Private Sub TwoTimes(ByVal n1 As Integer, ByVal n2 As Integer)
6: Trace.WriteLine((n1 + n2) * 2)
7: End Sub
8:
9: Private Sub TwoTimes(ByVal s As String)
10: Trace.WriteLine(s & s)
11: End Sub
12:
13: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
14: TwoTimes(123)
15: TwoTimes(123, 456)
16: TwoTimes("123")
17: End Sub
|
|
サンプル・プログラムをVB.NET用に書き換えたのサンプル・プログラム2 |
これを実行すると以下のようになる。
このように、引数の型や種類が異なる同じ名前のメソッドを宣言することをオーバーロードという。VB.NETでは、オーバーロードが可能となっている。VB 6ではデータは何でもとりあえずVariant型で受けて処理するという方法が使えたので、オーバーロードの必要性は薄かったかもしれない。だが、VB.NETでデータ型を厳密に扱うプログラミングを行うようになると、必須となる機能といえる。同じ名前のメソッドでも、データ型を細かく分けて別々のメソッドとして処理するプログラミングをするようになれば、避けては通れない機能である。
なお、以下の要素が異なっていても、異なるメソッドとは認識されない。
- 型メンバの修飾子(SharedやPrivateなど)
- パラメータの修飾子(ByVal や ByRefなど)
- パラメータの名前
- メソッドの戻り値の型
- プロパティの要素型
オーバーロードは、メソッドだけでなく、コンストラクタやプロパティでも使用できる。
Protectedアクセス
メソッドなどには、PrivateやPublicといったキーワードを付けて、それにアクセスできる範囲をコントロールすることができる。ソース・コードの意図しない行から呼び出されないために、このようなキーワードを正しく使うことは、ソフトウェアの品質を上げるために重要な意味がある。この連載のサンプル・プログラムの中にも、分かりやすさのためにPublicとしているが本当はPublicにすべきではないケースも含まれる。それはさておき、VB 6にはなかった新しいキーワードProtectedがVB.NETには存在している。これは、継承を行った場合に意味がある機能を割り当てられたもので、継承がないVB 6にないのは当然といえる機能である。以下に、Protectedを使用したサンプル・プログラムを示す。
1: Public Class A
2: Protected Sub Sample1()
3: Trace.WriteLine("クラスAのSample1が呼ばれました")
4: End Sub
5: Public Sub Sample2()
6: Sample1()
7: End Sub
8: End Class
9:
10: Public Class B
11: Inherits A
12: Public Sub Sample3()
13: Sample1()
14: End Sub
15: End Class
16:
17: Public Class Form1
18: Inherits System.Windows.Forms.Form
19:
20: …Windows フォーム デザイナで生成されたコード…
21:
22: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
23: Dim instanceA As New A()
24: Dim instanceB As New B()
25: 'instanceA.Sample1()
26: instanceA.Sample2()
27: 'instanceB.Sample1()
28: instanceB.Sample2()
29: instanceB.Sample3()
30: End Sub
31: End Class
|
|
Protectedキーワードを使用したサンプル・プログラム3 |
これを実行すると以下のようになる。
1: クラスAのSample1が呼ばれました
2: クラスAのSample1が呼ばれました
3: クラスAのSample1が呼ばれました
|
|
サンプル・プログラム3の実行結果 |
Publicキーワードはどこからでも呼び出せることを指定し、Privateキーワードは同じクラス内からのみ呼び出せることを指定する。それに対して、Protectedキーワードは、同じクラスと、そのクラスを継承したクラスからのみ呼び出せることを指定する。そのため、6行目のように、同じクラスからの呼び出しは実現できる。また、13行目のように、クラスAを継承したクラスBからも呼び出すことができる。しかし、継承関係のないForm1クラス内からは呼び出せず、25行目や27行目の行からシングルクォートを取り除いて有効にすると、ビルド・エラーになる。Protectedは継承を多用する場合に便利な機能であり、知っておく価値がある。
継承を禁止するNotInheritableキーワード
クラスを宣言する際に、必ず継承しなければならないことを示すMustInheritキーワードについてはすでに解説した。このほかに逆の効能を持つキーワード、NotInheritableがある。以下のサンプル・プログラムは、それを使用した例である。
1: Public NotInheritable Class A
2: Private a As Integer
3: End Class
4:
5: Public Class B
6: Inherits A
7: Private b As Integer
8: End Class
|
|
継承を禁止するNotInheritableキーワードを使用したサンプル・プログラム12(コンパイル・エラーとなる) |
このように記述すると、ビルド時にエラーになる。1行目でクラスAには、NotInheritableキーワードが付いているので、クラスAを継承することは出来ない。6行目で、クラスAを継承しようとしているが、これはエラーになる。内部の実装にトリックを使ったりして、継承すると不都合が起きるようなクラスを作った場合は、このキーワードを付けておくと、誤って継承してもエラーが起きて気付くことができる。
Insider.NET 記事ランキング
本日
月間