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

VB開発者のためのポリモーフィズム(多態性)入門
―第8章 ポリモーフィズム〜クラスの操作方法(前編)―

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

8.1.3 オーバーライドのしくみ

 ではいよいよ、ポリモーフィズムを実現するしくみを説明しましょう。まず初めに次のプログラムを見てください。

Class Music

  Public Overridable Sub baseInfo()
    Console.WriteLine("Music")
  End Sub

End Class

' 派生クラス
Class Song : Inherits Music

  ' 同じメソッドを定義
  Public Overrides Sub baseInfo()
    Console.WriteLine("Song")
  End Sub

End Class

' 派生クラス
Class Symphony : Inherits Music

  ' 同じメソッドを定義
  Public Overrides Sub baseInfo()
    Console.WriteLine("Symphony")
  End Sub

End Class

Class MainClass
  Public Shared Sub Main()

    ' Musicクラスの参照変数
    Dim m As Music

    ' Songクラスのインスタンスを代入(アップキャスト)
    m = New Song()

    ' SongクラスのbaseInfoが実行される
    m.baseInfo()             ' 出力値:Song

    ' Symphonyクラスのインスタンスを代入
    m = New Symphony()

    ' 今度はSymphonyクラスのbaseInfoが実行される
    m.baseInfo()             ' 出力値:Symphony

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

 Musicクラスを基本クラスにして、SongクラスとSymphonyクラスを派生しています。Mainメソッドでは、まず基本クラスであるMusicクラスへの参照型変数を定義しています。そして、Songクラスのインスタンスをアップキャストして代入し、baseInfoメソッドを呼び出しています。

 さて、このbaseInfoメソッドでは、どのクラスのメソッドが呼び出されるのでしょうか。

 変数mは、Musicクラスを参照する変数ですが、MusicクラスのbaseInfoメソッドが実行されるわけではありません。ここでは、Songクラスのメソッドが呼び出されます。

 変数mの中身は、Songクラスのインスタンスを指しているので、宣言時の型に従うのではなく、Songクラスのメソッドが実行されるというわけです。

 同様に、Symphonyクラスのインスタンスを代入すると、同じbaseInfoメソッドの呼び出しでも、今度はSymphonyクラスのメソッドが実行されます。

 このように、宣言した変数の型ではなく、インスタンスに従って、呼び出される仮想メソッドが決まります。このような性質のことを、ポリモーフィズム(多態性)と呼びます。

図8-3 オーバーライドのしくみ

8.1.4 メソッドの隠蔽

 Shadowsキーワードを使ってメソッドを隠蔽すると、実は、ポリモーフィズムの性質まで隠蔽されてしまいます。次のプログラムを見てください。

' 基本クラス
Class Music

  Public Overridable Sub baseInfo()
    Console.WriteLine("Music")
  End Sub

End Class

' 派生クラス
Class Music2 : Inherits Music

  ' Shadowsキーワードでメソッドを隠蔽
  Public Shadows Sub baseInfo()
    Console.WriteLine("Music2")
  End Sub

End Class

Class MainClass
  Public Shared Sub Main()

    ' Musicクラスの参照変数
    Dim m As Music

    ' Music2クラスのインスタンスを代入
    m = New Music2()

    ' MusicクラスのbaseInfoが実行される
    m.baseInfo()

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

 派生クラスのMusic2クラスでは、Shadowsキーワードを使ってbaseInfoメソッドを定義しています。

 Mainメソッドでは、先ほどと同じように、Musicクラスの参照変数に、Music2クラスのインスタンスを代入しています。そして、baseInfoメソッドを呼び出します。

 すると今度は、Music2クラスのメソッドではなく、変数が示すMusicクラスのbaseInfoメソッドが実行されるのです。

 このように隠蔽では、ポリモーフィズムが働かなくなってしまいます。派生クラスとはいうものの、メソッドの継承関係を断ち切ってしまうのが、隠蔽なのです*2

*2) 隠蔽の使い所としては、基本クラスの変更まではしたくないが、メソッドの呼び出しはそのままで、まったく別の実装にしたいケースなどでしょう。

8.1.5 NotInheritableキーワード

 自作のプログラムでは、あまり使わないとは思いますが、クラスライブラリなどでは、NotInheritableというキーワードを付けてクラスを宣言しているケースがあります。これは、継承を禁止しているのです。

 継承を禁止するケースとしては、派生クラスでは、想定した動作が保証できないので、継承を許したくないといった場合です。

 以下のように、NotInheritableキーワードを付けてクラスを宣言すると、継承を禁止することができます。

アクセス修飾子 NotInheritable Class クラス名

  ' クラス定義

End Class
[構文]NotInheritableクラスの宣言

 次のように、NotInheritableクラスを継承しようとすると、コンパイル時にエラーとなります。

' 基本クラス
NotInheritable Class Base
  Private a As Integer
End Class

' 派生させることはできません
Class Derived : Inherits Base
End Class
[サンプル]notinherit.vb

8.1.6 抽象メソッド/抽象クラス

 抽象メソッドとは、戻り値の型とパラメータリストだけを宣言したメソッドです。実際の中身の処理は、派生クラスで実装します。仮想メソッドの場合は、基本クラスにも処理を定義できましたが、抽象メソッドは、基本クラスでは宣言だけとなります。

 抽象メソッドの宣言は、MustOverrideキーワードを付けて行います。宣言だけで、メソッドの処理ブロックはありません。

アクセス修飾子 MustOverride 戻り値の型名 メソッド名( パラメータリスト )
[構文]抽象メソッドの宣言

 抽象メソッドを含むクラスでは、そのクラス自体も、抽象クラスとして宣言する必要があります。クラスの宣言の方には、MustInheritキーワードを付けます。

アクセス修飾子 MustInherit Class クラス名

  ' クラス定義

End Class
[構文]抽象クラスの宣言

 具体的なプログラム例は、以下のようになります。

' 抽象クラス(基本クラス)
MustInherit Class Music

  ' 抽象メソッド
  Public MustOverride Sub getInfo()

End Class

' 派生クラス
Class Song : Inherits Music

  ' Overridesを付ける
  Public Overrides Sub getInfo()
    Console.WriteLine("Song")
  End Sub

End Class

Class MainClass
  Public Shared Sub Main()

    Dim s As New Song()
    s.getInfo() ' 出力値:Song

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

 抽象クラスを継承したクラスは、抽象メソッドの処理を必ずオーバーライドする必要があります。上記の例では、getInfoメソッドが抽象メソッドなので、派生クラスのSongクラスで処理の内容を定義しています。

 次回は、今回に引き続き、「8.2 インターフェイス」を転載します。End of Article


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

本日 月間