連載

プロフェッショナルVB.NETプログラミング

第9回 オブジェクト関連(前編)

(株)ピーデー
川俣 晶
2002/06/15

Page1 Page2 Page3

コンストラクタへの引数

 インスタンス内部の初期値を、インスタンスを生成する側から設定するケースを考えてみよう。例えば、名前と年齢を保持する2つの変数を持つクラス“Class1”のインスタンスを生成して利用する場合は、この2つの変数に値を設定する必要がある。VB 6では、インスタンスを生成してから、必要な値を設定するので、個別の値を設定する手段をクラスの中に用意しなければならない。以下は、プロパティ経由で値を設定する機能を含めて作成してみたクラスである。

  1: Private name0 As String
  2: Private age0 As Integer
  3:
  4: Public Property Let name(ByVal s As String)
  5:   name0 = s
  6: End Property
  7:
  8: Public Property Let age(ByVal a As Integer)
  9:   age0 = a
 10: End Property
 11:
 12: Public Sub OutputData()
 13:   Debug.Print name0
 14:   Debug.Print age0
 15: End Sub
プロパティ経由でクラス内の変数を設定できるVB 6のサンプル・プログラム5

 これを利用する側のコードは、以下のような感じになる。

 1: Private Sub Form_Load()
 2:   Dim taro As New Class1
 3:   taro.name = "Taro"
 4:   taro.age = 17
 5:   taro.OutputData
 6: End Sub
サンプル・プログラム5を利用するVB 6のサンプル・プログラム6

 これを実行すると以下のようになる。

 1: Taro
 2:  17
サンプル・プログラム6の実行結果

 これをVB.NET用として書き換えてみよう。クラス内の変数への値の設定は1回限りとすれば、コンストラクタの引数を経由して値を入れてしまうことができる。そのようなクラスを記述してみたのが下記のサンプル・プログラムである。

  1: Public Class Class1
  2:   Private name As String
  3:   Private age As Integer
  4:
  5:   Public Sub OutputData()
  6:     Trace.WriteLine(name)
  7:     Trace.WriteLine(age)
  8:   End Sub
  9:
 10:   Public Sub New(ByVal n As String, ByVal a As Integer)
 11:     name = n
 12:     age = a
 13:   End Sub
 14: End Class
コンストラクタの引数によりクラス内の変数を設定するVB.NETのサンプル・プログラム7

 このソースのNewメソッドに引数が付いていることが分かるだろう。この引数は以下のように記述することで利用できる。

 1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 2:   Dim taro As New Class1("Taro", 17)
 3:   taro.OutputData()
 4: End Sub
サンプル・プログラム7を利用するVB.NETのサンプル・プログラム8

 これを実行すると以下のようになる。

 1: Taro
 2: 17
サンプル・プログラム8の実行結果

 このソースの2行目のように、As Newキーワードを使用した宣言のときに、クラス名の後に引数を記述することができる。

 コンストラクタに引数を渡すのは、以下のような書式でも可能である。

 1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 2:   Dim taro As Class1
 3:   taro = New Class1("Taro", 17)
 4:   taro.OutputData()
 5: End Sub
コンストラクタ呼び出しを別の書式に変えたVB.NETのサンプル・プログラム9

インターフェイス機能の変更点

 VB 6には、継承はなくてもインターフェイスの機能があり、簡単なポリモーフィズムぐらいなら記述することができた。しかし、このインターフェイス関係の機能が、VB 6とVB.NETでは大幅に変化している。この実例を見てみよう。

 ここでは、クラス1個、インターフェイス1個を持つサンプル・プログラムを記述してみよう。そして、インターフェイス経由で、クラス内に記述したメソッドを呼び出してみよう。まずは、インターフェイス“Class2”を定義したソースである。

 1: Public Sub OutputMessage(ByVal msg As String)
 2: End Sub
インターフェイス“Class2”を定義したVB 6のサンプル・プログラム10

 次に、このインターフェイスを実装するクラス“Class1”を記述してみた。

 1: Implements Class2
 2: Public Sub Class2_OutputMessage(ByVal msg As String)
 3:   Debug.Print msg
 4: End Sub
サンプル・プログラム10のインターフェイスを実装したVB 6のサンプル・プログラム11

 これらを利用して、インターフェイス経由でクラスのメソッドを呼び出すコードとして以下のようなものを書いてみた。

 1: Private Sub Form_Load()
 2:   Dim obj As Class1
 3:   Set obj = New Class1
 4:   Dim interf As Class2
 5:   Set interf = obj
 6:   interf.OutputMessage "Hello!"
 7: End Sub
インターフェイス経由でクラスのメソッドを呼び出すVB 6のサンプル・プログラム12

 これを実行すると以下のような出力が得られる。そのことに疑問はないと思う。

 1: Hello!
サンプル・プログラム12の実行結果

 さて、このソースをVB.NET用に書き換えるにはどうすればよいのだろうか。1つずつソースを置き換えてみよう。まず、インターフェイスの定義は以下のようになる。

 1: Public Interface Class2
 2:   Sub OutputMessage(ByVal msg As String)
 3: End Interface
インターフェイスを定義しているサンプル・プログラム10をVB.NETで書き換えたサンプル・プログラム13

 見ての通り、相当違っていることが分かるだろう。まず、VB 6ではインターフェイスはクラスの一種として作成したが、VB.NETではインターフェイスはインターフェイスという機能として扱われている。そのため1行目のように、“Public Interface”で始めて、3行目のように“End Interface”で終わる必要がある。そして、肝心の中身の定義も大きく異なっている。VB 6では中身のないSubを記述することでインターフェイスのメンバを定義したが、VB.NETでは、最初から中身がないものとして扱われる。これは、最初に1行目でインターフェイスであることを明示していることにより、中身が存在しないことが明らかだからである。その結果、中身の終わりを示すEnd Subを記述する必要はなく、実際、上記のソースにはEnd Subが含まれない。

 もう一点の相違は、Subの手前に付いていたPublicキーワードが、VB.NETでは不要になったことだ。インターフェイスでは、Privateにすることに意味がないので、Publicキーワードをわざわざ付ける意味はない。もし、インターフェイスにPrivateな定義が含まれていたとしても、それをほかのクラスなどから参照できないため、実装することができないのである。

 なお、ここではVB 6のソースに合わせてClass2という名前でインターフェイスを作成しているが、VB.NETらしいネーミングとしてはそぐわない。例えばInterface2というような名前の方が適切だろう。

 さて、次は、このインターフェイスを実装するクラスのサンプル・プログラムである。

 1: Public Class Class1
 2:   Implements Class2
 3:   Public Sub OutputMessage(ByVal msg As String) Implements Class2.OutputMessage
 4:     Trace.WriteLine(msg)
 5:   End Sub
 6: End Class
サンプル・プログラム13のインターフェイスを実装するVB.NETのサンプル・プログラム14

 ここで注目する必要があるのは、3行目である。ここで、インターフェイスで定義されたメソッドの内容を実装している。その際、VB 6では、クラス名とメソッド名を含む独特の名前を用いて、インターフェイスの実装であることを示していた。今回のサンプルなら、インターフェイスのクラス名がClass2で、メソッド名がOutputMessageであるため、Class2_OutputMessageという名前のメソッドを記述していた。しかし、VB.NETではそのようなネーミングを使用せず、その代わりに、Implementsキーワードを使う。Implementsキーワードの後に、インターフェイス名とメソッド名をピリオド区切りで記述する。名前空間名を含む長い名前であってもよい。これにより、どのインターフェイスのどのメソッドを実装するのかが明示される。

 最後にこれらのソースを呼び出す側のコードを以下に示す。

 1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 2:   Dim obj As Class1
 3:   obj = New Class1()
 4:   Dim interf As Class2
 5:   interf = obj
 6:   interf.OutputMessage("Hello!")
 7: End Sub
サンプル・プログラム14を利用するサンプル・プログラム15

 これを実行すると以下のようになる。

 1: Hello!
サンプル・プログラム15の実行結果

 インターフェイスの定義と実装は変わったが、利用する方法は変わってはいないことが分かるだろう。


 INDEX
  連載 プロフェッショナルVB.NETプログラミング
  第9回 オブジェクト関連(前編)
    1.オブジェクト関連のタイミングの違い
  2.コンストラクタへの引数
    3.プロパティ構文の大変更
 
「プロフェッショナルVB.NETプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間