連載

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

Chapter 10 継承とポリモーフィズム

株式会社ピーデー 川俣 晶
2004/06/24


 本記事は、(株)技術評論社が発行する書籍『VB6プログラマーのための入門 Visual Basic .NET 独習講座』の一部分を許可を得て転載したものです。同書籍に関する詳しい情報については、本記事の最後に掲載しています。

クラス・ライブラリに見るポリモーフィズムの実例 - その1

 .NET Frameworkでは、各所でポリモーフィズムを活用している。その一例を以下に示そう。フォーム上のPictureBoxに、BMPファイルとEMFファイル(拡張メタファイル)を表示するサンプル・プログラムを作成してみた。

 内部に画像を保持する変数を持たせ、BMPファイルを読み込んでその変数に画像への参照を入れるボタンと、EMFファイルを読み込んでその変数に画像への参照を入れるボタンを用意する。そして、フォーム上のPictureBoxに変数の画像を表示させるボタンも持たせる。こう書くと簡単そうだが、クラス・ライブラリでは、BMPファイルはSystem.Drawing.Bitmapクラス(Bitmapクラス)が扱い、EMFファイルはSystem.Drawing.Imaging.Metafileクラス(Metafileクラス)が扱うため、同じクラスで処理できないのがポイントである

 では、このプログラムを作成してみよう。まず、Visual BasicプロジェクトのWindowsアプリケーションの設定を用いて、新しいプロジェクトを作成する。次にフォーム上にPictureBoxを1個、Buttonを3個配置する。ボタンのラベルには適当な文字列を入れておく(図10-41)。

●図10-41 Visual Studio .NETのデザイン画面

 プログラムコードは以下のようになる。

 1: Imports System.Drawing.Imaging
 2:
 3: Public Class Form1
 4:   Inherits System.Windows.Forms.Form
 5:
 6: …Windows フォーム デザイナで生成されたコード…
 7:
 8:   Dim img As image
 9:
10:   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
11:     img = New Bitmap("c:\test.bmp")
12:   End Sub
13:
14:   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
15:     img = New Metafile("c:\test.emf")
16:   End Sub
17:
18:   Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
19:     PictureBox1.Image = img
20:   End Sub
21: End Class
リスト10-42 BMPファイルとEMFファイルの両方を表示するプログラム

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

●図10-43 リスト10-42の実行例(BMPファイル(左)および、EMFファイル(右)をロードして表示した例)

 見てのとおり、極めて簡単である。BMPファイルはSystem.Drawing.Bitmapクラスで、EMFファイルはSystem.Drawing.Imaging.Metafileクラスで扱うにもかかわらず、クラスの種類の判定などを行うコードがいっさいないのは、ポリモーフィズムのおかげである。

 実は、System.Drawing.BitmapクラスとSystem.Drawing.Imaging.Metafileクラスは、いずれも、System.Drawing.Imageクラスを継承しており、PictureBoxのImageプロパティもSystem.Drawing.Imageクラスのインスタンスを受け入れるようになっている。

 つまり、System.Drawing.Bitmapクラスだろうと、EMFファイルのSystem.Drawing.Imaging.Metafileクラスだろうと、インスタンスの参照をSystem.Drawing.Imageクラスの参照に変換できるので、そのままImageプロパティに代入可能というわけである。まさに、ポリモーフィズムの効力が発揮されているといえる。もちろん、ただ単に代入できるだけではなく、PictureBoxクラスは具体的な画像の内容を知ることができ、それを活用して表示することができるわけである。

 もし、このような便利な継承関係を意識しないで記述するなら、ソース・コードは以下のようになる(リスト10-44)。

 1: Imports System.Drawing.Imaging
 2:
 3: Public Class Form1
 4:   Inherits System.Windows.Forms.Form
 5:
 6: …Windows フォーム デザイナで生成されたコード…
 7:
 8:   Private imgBitmap As Bitmap
 9:   Private imgMetafile As Metafile
10:   Private bBitmap As Boolean
11:
12:   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
13:     imgBitmap = New Bitmap("c:\test.bmp")
14:     bBitmap = True
15:   End Sub
16:
17:   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
18:     imgMetafile = New Metafile("c:\test.emf")
19:     bBitmap = False
20:   End Sub
21:
22:   Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
23:     If bBitmap Then
24:       PictureBox1.Image = imgBitmap
25:     Else
26:       PictureBox1.Image = imgMetafile
27:     End If
28:   End Sub
29: End Class
リスト10-44 System.Drawing.Imageクラスの継承関係を意識しないで記述したプログラム

 行数を比較すれば差は歴然だろう。ポリモーフィズムを活用すれば21行で済んだものが、使わないと29行に膨らんでいる。また、ソースの分かりやすさや安全性も低下している。何より重要なのは、.NET Frameworkのクラス・ライブラリはすでに存在するものであって、新たに取り組んで開発すべき新しい何かではないことである。すでにあるものを有効活用するために、ポリモーフィズム(あるいは、より広範囲のオブジェクト指向)という考え方は知っておく価値がある。また、知るだけでなく、実際に使って慣れておくことも有意義だろう。ポリモーフィズムのようなごく基本的な考え方は、いちいち頭で考えて使うものではなく、自然にコーディングしているうちに出てくるべきものである。

クラス・ライブラリに見るポリモーフィズムの実例 - その2

 System.Drawing.Imageクラスには、FromFileという名前の共有メソッドがある。このメソッドは、BMPファイルやEMFファイルを読み込む機能を持っている。読み込んだ結果は、System.Drawing.Imageクラスのインスタンスへの参照として返される。しかし、System.Drawing.Imageクラスは抽象的なクラスであって、BMPファイルを持てるのはSystem.Drawing.Bitmapクラスであり、EMFファイルはSystem.Drawing.Imaging.Metafileクラスであるはずだ。

 この謎を解くには、実際にFromFileメソッドが返しているインスタンスのクラスがSystem.Drawing.Bitmapクラスであったり、System.Drawing.Imaging.Metafileクラスであったりするという事実を知らねばならない。定義上、このメソッドはSystem.Drawing.Imageクラスのインスタンスへの参照を返すことになっているが、このクラスを継承したクラスのインスタンスへの参照が返されても、コンパイラはエラーにならないのである。実際にそれを確認するサンプル・プログラムを記述してみた。このサンプル・プログラムでは、フォーム上に表示しているオブジェクトのクラス名を表示するためのLabelを追加している(リスト10-45)。

 1: Public Class Form1
 2:   Inherits System.Windows.Forms.Form
 3:
 4: …Windows フォーム デザイナで生成されたコード…
 5:
 6:   Dim img As Image
 7:
 8:   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 9:     img = Image.FromFile("c:\test.bmp")
10:   End Sub
11:
12:   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
13:     img = Image.FromFile("c:\test.emf")
14:   End Sub
15:
16:   Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
17:     PictureBox1.Image = img
18:     Label1.Text = img.GetType().FullName
19:   End Sub
20:
21: End Class
リスト10-45 System.Drawing.ImageクラスのFromFileメソッドを試したプログラム

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

●図10-46 リスト10-45の実行例(BMPファイル(左)および、EMFファイル(右)をロードして表示した例)
 
画面一番下にはフォーム上に表示しているオブジェクトのクラス名を表示している。

 簡単な内容なので、詳しい説明は割愛する。18行目で、Imageプロパティに代入したインスタンスのGetTypeメソッドを呼び出して型情報を得て、FullNameプロパティでクラス名を得ている。表示結果を見て分かるとおり、FromFileメソッドの戻り値の型はSystem.Drawing.Imageであるが、実際に返されているのは、System.Drawing.Bitmapクラスであったり、System.Drawing.Imaging.Metafileクラスであったりしている

 このような挙動を見せるクラスを、トラブルを起こすことなく活用するには、ポリモーフィズムや継承に関する一通りの知識が必要となる。しかし、ひとたびそれらの知識を得れば、標準で提供されるクラス・ライブラリを活用して、これまでとはひと味違うソース・コードを記述できるようになるだろう。End of Article

VB6プログラマーのための入門 Visual Basic .NET 独習講座』

 本記事は、(株)技術評論社が発行する書籍『VB6 プログラマーのための 入門 Visual Basic .NET 独習講座』から
許可を得て転載したものです。

【本連載と書籍の関係について 】
 この書籍は、本フォーラムで連載した「連載 プロフェッショナルVB.NETプログラミング」を大幅に加筆修正し、発行されたものです。技術評論社、および著者である川俣晶氏のご好意により、書籍の内容を本フォーラムの連載記事として掲載させていただけることになりました。

技術評論社の解説ページ

ご注文はこちらから
 

 INDEX
  [連載] 改訂版 プロフェッショナルVB.NETプログラミング
  Chapter 10 継承とポリモーフィズム
    1.Inheritsステートメントによる継承機能/クラス内で継承元クラスのメソッドを呼ぶ
    2.Windows FormにおけるInheritsステートメントの効果/継承時にメソッドの動作を入れ替える/Overridesキーワードを使って継承時にメソッドの動作を入れ替える
    3.中身のないメソッドに対し、継承により中身を入れる/Protectedアクセス/継承を禁止するNotInheritableキーワード
    4.ポリモーフィズム(異なる機能と共通の呼び出し方法)
    5.ポリモーフィズム(ソース・コードの弱点を分析/ポリモーフィズムを用いた書き換え)
  6.クラス・ライブラリに見るポリモーフィズムの実例 - その1/その2
 
「改訂版 プロフェッショナル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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH