書籍転載
文法からはじめるプログラミング言語Microsoft Visual Basic入門

VB開発者のためのインターフェイス入門
―第8章 ポリモーフィズム〜クラスの操作方法(後編)―

WINGSプロジェクト 高江 賢(監修 山田 祥寛)
2010/10/06
Page1 Page2

本コーナーは、日経BPソフトプレス発行の書籍『文法からはじめるプログラミング言語Microsoft Visual Basic入門』の中から、特にInsider.NET読者に有用だと考えられる章や個所をInsider.NET編集部が選び、同社の許可を得て転載したものです。基本的に元の文章をそのまま転載していますが、レイアウト上の理由などで文章の記述を変更している部分(例:「上の図」など)や、図の位置などを本サイトのデザインに合わせている部分が若干ありますので、ご了承ください。『文法からはじめるプログラミング言語Microsoft Visual Basic入門』の詳細は「目次情報ページ」もしくは日経BPソフトプレスのサイトをご覧ください。

ご注意:本記事は、書籍の内容を改変することなく、そのまま転載したものです。このため用字用語の統一ルールなどは@ITのそれとは一致しません。あらかじめご了承ください。

8.2 インターフェイス

 次に、抽象クラスと同様なことを実現する、もう1つ別の方法を説明しましょう。インターフェイスと呼ばれる機能で、抽象クラスを拡張したものです。

 ただし、インターフェイスはクラスではないので、単一継承しか許されないという制約もありませんし、複数のインターフェイスを「継承」することもできます。

8.2.1 インターフェイスとは

 インターフェイスとは、メソッドの呼び出し方だけを定めたものです。実際の処理の内容は、インターフェイスを引き継いだクラスで定義することになります。これを、インターフェイスを実装する、という言い方をします。実は、インターフェイスの場合は、継承するとは言わないのです。

 インターフェイスの概念を、テレビリモコンで例えると、インターフェイスがリモコンで、インターフェイスを実装したクラスがテレビということになります。テレビを利用する人は、個々のテレビの使い方を知らなくても、リモコンというインターフェイスだけを知っていれば、操作ができます。

 リモコン(インターフェイス)は、音量やチャンネル切り替えの処理(メソッド)を呼び出すだけで、実際の処理はテレビ(インタフェースを実装したクラス)が行います。リモコンを操作する人は、実際にテレビがどう処理をするのか理解する必要がありません。

図8-4 インターフェイスの概念

 インターフェイスは、次のようにInterfaceステートメントを用いて定義します。インターフェイスのアクセスレベルは、既定でFriendですが、必要に応じてPublicなどを指定することができます。

アクセス修飾子 Interface インターフェイス名

  ' メンバの宣言

End Interface
[構文]Interfaceステートメント

 インターフェイスを実装するクラスでは、次のようにImplementsキーワードを付けて定義します。

アクセス修飾子 Class クラス名 : Implements インターフェイス名

  ' クラス定義

End Class
[構文]インターフェイスを実装したクラスの定義

 また、実装したメソッドには、メソッド名に続けて、Implementsキーワードと、インターフェイス名.メソッドを指定して、どのメソッドを実装したのかを示す必要があります。通常、実装するメソッド名とインターフェイスのメソッド名は同一にしますが、異なる名前を定義することもできます。

メソッド名( パラメータリスト ) Implements インターフェイス名.メソッド
[構文]インターフェイスを実装したメソッドの宣言

 以下に、プログラム例を示します。

' インターフェイス
Interface IGetInfo
  Sub getInfo()
End Interface

' IGetInfoインターフェイスの実装クラス
Class SampleClass : Implements IGetInfo

  Public Sub getInfo() Implements IGetInfo.getInfo
    Console.WriteLine("SampleClass")
  End Sub

End Class

Class MainClass
  Public Shared Sub Main()

    Dim s As New SampleClass()

    s.getInfo() ' 出力値:SampleClass

  End Sub
End Class
[サンプル]interface.vb

 インターフェイスの名前は、規定があるわけではありませんが、クラスと区別するために、先頭にIを付けることが多いようです。インターフェイスのメンバには、通常のメソッドの他に、特殊なメソッドである、プロパティ、イベントを含めることができます。

 また、Implementsキーワード以下に、実装されるインターフェイスのメンバをコンマ区切りにして、複数指定することができます。したがって、次の例に示すように、インターフェイスで定義されている複数のメソッドを、1つのメソッドで実装するということもできます。

Class SamplClass
  Implements I1, I2

  Public Sub Sample() Implements I1.m1, I1.m2, I2.m3, I2.m4
  ...
  End Sub

End Class

8.2.2 データ型としてのインターフェイス

 今度は、プロパティを含んだインターフェイスの例を見てみましょう。

' プロパティのインターフェイス
Interface IPoint

  ' プロパティ
  Property px() As Integer
  Property py() As Integer

End Interface

' プロパティのみのインターフェイスを実装
Class ReversePoint : Implements IPoint

  ' フィールド
  Private x As Integer
  Private y As Integer

  ' コンストラクタ
  Public Sub New(ByVal x As Integer, ByVal y As Integer)
    Me.x = x
    Me.y = y
  End Sub

  ' インターフェイスの実装
  Public Property px() As Integer Implements IPoint.px

    Get
      Return -x
    End Get

    Set(ByVal value As Integer)
      x = value
    End Set

  End Property

  Public Property py() As Integer Implements IPoint.py

    Get
      Return -y
    End Get

    Set(ByVal value As Integer)
      y = value
    End Set

  End Property

End Class

Class MainClass

  ' パラメータがIPointインターフェイスの共有メソッド
  Public Shared Sub DisplayPoint(ByVal point As IPoint)
    Console.WriteLine("x={0},y={1}", point.px, point.py)
  End Sub

  Public Shared Sub Main()

    Dim p1 As New ReversePoint(12, 300)

    ' プロパティの参照
    Console.WriteLine(p1.px)  ' 出力値:-12
    Console.WriteLine(p1.py)  ' 出力値:-300

    ' プロパティの参照
    DisplayPoint(p1)      ' 出力値:x=-12,y=-300

  End Sub
End Class
[サンプル]interface2.vb

 最初に、IPointインターフェイスの宣言です。インターフェイスのメンバにプロパティを宣言する場合は、Propertyステートメントだけを記述します。

 ReversePointクラスで、IPointインターフェイスを実装しています。プロパティのGetで符号を反転しています。Mainクラスでは、共有メソッドの定義と、インターフェイスを実装したクラスを使った処理を記述しています。インターフェイスを実装したReversePointクラスをインスタンス化すれば、pxとpyというプロパティにアクセスすることができます。

 ここで、注目してほしいのが、共有メソッドDisplayPointのパラメータがインターフェイスになっているところです。メソッド内では、インターフェイスで宣言したプロパティpxとpyを参照して値を出力しています。では、インターフェイスがパラメータになっているメソッドを呼び出すには、どう指定すればよいのでしょうか。プログラム例でわかるように、インターフェイスを実装したクラスのインスタンスを指定するのです。DisplayPoint(p1)のように、実際のメソッド呼び出しでは、IPointインターフェイスを実装したクラスのインスタンスを指定しています。

 これは、インターフェイスを実装したクラスのインスタンスは、実装元のインターフェイスに暗黙的に変換できることを示しています。

 Typeof...Is式で確かめてみましょう。Trueと表示されるはずです。

Console.WriteLine(TypeOf p1 Is IPoint)  ' 出力値:True

 DisplayPointメソッドのパラメータには、IPointインターフェイスを実装したクラスなら、どんなインスタンスでも指定できます。インターフェイスが、それを実装しているクラスをひとまとめにするデータ型となっているのです。先ほどの例は、インターフェイスをメソッドのパラメータとする例でしたが、もっと直接的に参照型として利用することもできます。以下のプログラムでは、サンプルのDisplayPointメソッドと同様の処理を記述しています。

Dim p1 As New ReversePoint(12, 300)
Dim point As IPoint = p1
Console.WriteLine("x={0},y={1}", point.px, point.py)

 インターフェイスを実装したクラスのインスタンスを、そのインターフェイスへの参照変数に代入することができます。


 INDEX
  [書籍転載]文法からはじめるプログラミング言語Microsoft Visual Basic入門
  VB開発者のためのインターフェイス入門
  1.インターフェイスとは/データ型としてのインターフェイス
    2.インターフェイスの多重継承、多重実装

インデックス・ページヘ 「文法からはじめるプログラミング言語Microsoft Visual Basic入門」


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 記事ランキング

本日 月間