Visual Basic 中級講座 |
Visual Basic 中学校 > 中級講座 >
ポリモーフィズムの考え方について説明します。具体的な活用例は次回以降に登場します。
概要 ・ ポリモーフィズムとは「同じ振舞いをするオブジェクトは同じように呼び出せるようにすべきである。」という考え方のこと。 ・ポリモーフィズムの考え方に基づいたプログラムでは、統一性・保守性・可読性・効率性に優れている。 ・ポリモーフィズムの具体的な活用例は次回以降に説明する。今回はポリモーフィズムの考え方を中心に説明する。 ・ポリモーフィズムを実現するために、継承、インターフェース、実行時バインディングの3つの機能が用意されている。 ・継承は(ポリモーフィズムの観点では、)基となるクラスからシグネチャのセットをまるごと引き継ぐ機能である。 ・インターフェースはシグネチャセットを定義して、それぞれのクラスで共有する機能。 |
ポリモーフィズムの説明では結局のところ「何がどう便利なのか?」というところがとても表現しにくくなってしまいます。
一般的なポリモーフィズムの説明を読んでみるとなんとかなく考え方や使い方はわかるけれども、それを使うとどのように良いことがあるのかという点がいま一つわかりにくいものが多いようです。
それも無理もないことで、ポリモーフィズムが役に立っている実践的な例を紹介しながらポリモーフィズムそのものについて説明しようとするとあまりにも長くなりすぎるため、たいていのポリモーフィズムの説明ではこの点がぼかされてしまうのです。
そこで、私は今回、「ポリモーフィズムがどのように便利なのか」がはっきりとわかるように説明を書くつもりでした。今、すべてを書き終わってから、この「はじめに」の部分を書いていますが、私の試みは失敗しました。
紹介するサンプルもつまらないものばかりです。読者はきっとこう思うでしょう。「何でいまさらこんな役にたたないサンプルを見なきゃいけないんだろう?」まはた、「こんなサンプルが一体何の役に立つと言うんだろう?」
どうしてもポリモーフィズムが便利なところが「はっきりと」アピールできないのです。でも、ポリモーフィズムは本当にすぐれた考え方で、不可欠なものです。
今回はアピールが不十分になってしまいましたが、次回以降具体例もまじえて「どう便利なのか」という点に切り込んでいきたいと思いますので、よろしくお付き合い願います。
前回も説明しましたが、ポリモーフィズムとは「同じ振舞いをするオブジェクトは同じように呼び出せるようにすべきである」という考え方のことで、「多態性」と呼ばれる場合もあります。
今回はこのポリモーフィズムを実際にプログラムの中で便利に利用する方法を紹介します。
.NET Frameworkのクラスライブラリはマイクロソフトの設計によってうまい具合にポリモーフィズムが実装されていますので、.NET Frameworkのクラスライブラリの中でポリモーフィズムの恩恵を受けることはすぐに可能です。まずは、この例を紹介し、その後で、自分で作成するクラスにポリモーフィズムを実装する例も紹介します。
ポリモーフィズムはわざわざ意識して使用しなくても、たいていのプログラムの中で既に利用されています。
次のプログラムはその例です。
このプログラムを実行する前にフォームにButtonとTextBoxを配置してください。配置する順番も重要で、まずButtonを配置して、その次にTextBoxを配置してください。
Private Sub
Button1_Click(ByVal sender
As System.Object,
ByVal e As System.EventArgs)
Handles Button1.Click Dim NextControl As Control NextControl = Me.GetNextControl(Button1, True) NextControl.Text = "こんにちは!" End Sub |
■リスト1
このプログラムを実行するとTextBoxに「こんにちは!」と表示されます。
ここで注目してい欲しいのはこのプログラムでは結果としてTextBoxのTextプロパティに値をセットしているにもかかわらず、TextBoxクラスが一切登場していないことです。もちろん、実行時には変数NextControlがTextBoxのインスタンスを表すことになるのですが、プログラム段階ではそのようなことは一切明示されていません。
このプログラムをみただけでは、一体何のTextプロパティが「こんにちは!」になるのかわからないのです。
このことをもっとよく理解するために、今度はフォームからTextBoxを削除して、代わりにComboBoxを配置してください。そしてプログラムを実行すると今度はComboBoxに「こんにちは!」と表示されます。
このようなことはどうして可能なのでしょうか?また、何のためにこのような書き方ができるようになっているのでしょうか?
「どうして」に直接答えると、TextBoxもComboBoxもControlクラスを継承しており、TextプロパティはこのControlクラスで定義されているプロパティだからです。
上記のプログラムはControlクラスを継承しているクラスに対してはTextBoxやComboBox以外のクラスでも有効に動作します。
「継承」については別の機会に説明しますが、簡単に説明すると継承とは「機能を引き継いで新しいクラスを作成すること」です。
「何のために」このような書き方ができるようになっているのかは直観的にわかっていただけると思いますが、ありていにいえば便利だからです。もし、対象がTextBoxのときとComboBoxのときとでプログラムをかえなければいけないとすると、上記の例のような単純なプログラムでも2通りのパターンを用意しておかなければいけないことになります。そして、実際にはコントロールはこの他にもLabelやFormなどさまざまな種類の物があるので、これだけのためにかなり大量のプログラムが必要になってしまいます。
VBではすべてのコントロールはControlクラスを継承しているので、安心して上記のような書き方ができるようになっているわけです。
NextControlをObject型にして同じことを行うこともできます。このとき、「継承」ではなく「実行時バインディング」という仕組みが働きます。実行時バインディングについては後ろの方で説明しています。 |
この現象について考えてみるとTextBoxやComboBox、Label,FormなどのTextプロパティはどれもコントロールに文字列を表示するという同じ振舞いをします。もちろん、その振舞いを実現させるためにマイクロソフトのプログラマが書いたプログラムはそれぞれ異なるはずですが、我々人間から見ると文字列を表示するという同じ振舞いに見えます。
同じ振舞いをするのですから、同じようにプログラムできれば便利です。もし、TextBoxの文字列はTextプロパティ、Labelの文字列はCaptionプロパティ、Formの文字列はTitleプロパティで設定するなどというような区別があったら不便この上ないでしょう。
VBでは文字列を表示する振舞いは、同じようにTextプロパティを使用して呼び出せるようになっているのです。
これがポリモーフィズムです。冒頭に掲げた「同じ振舞いをするオブジェクトは同じように呼び出せるようにすべきである」という意味がわかっていただけるのではないでしょうか?
ポリモーフィズム的発想 | ・なんであれ文字列の表示はTextプロパティに統一 ・なんであれ外部ファイルの取り込みはImportメソッドに統一 ・なんであれオブジェクトの破棄はDisposeメソッドに統一 |
非ポリモーフィズム的発想 | ・文字列の表示はTextBoxならTextプロパティ、LabelならCaptionプロパティ ・CSVの取り込みはImportCSVメソッド、XMLの取り込みはImportXMLメソッド ・オブジェクトの破棄はあるものはCloseメソッド、あるものはDisposeメソッド |
■表1:ポリモーフィズム的発想の例。これは「発想の例」であって、この表のメソッド・プロパティの多くは実在しないものです。
なお、ポリモーフィズム=優秀、非ポリモーフィズム=劣等ということではありませんのでご注意を願います。
ここまでの説明を読むと、ようするに「同じ機能のメソッドやプロパティの名前は統一しましょうというのがポリモーフィズム?」と感じられるかもしれません。
これはポリモーフィズムの考え方の一側面ではありますが、これだけでがポリモーフィズムではありません。
ポリモーフィズムの考えかたでもうひとつの重要な側面は実際に何を行うかは呼び出される各クラスで定義し、呼び出し側は機能を呼び出すだけという点です。
■図1
この図は呼び出し側と呼び出され側の関係を模式的に示したものですが、Textプロパティだけを介してこの2つが連携していることがわかります。
この仕組みが複数のクラスで同時に実装されるときに何が起こるか図にしたものが以下です。
■図2
それぞれの処理はクラスによって異なりますが、呼び出し側はどの場合もTextプロパティを呼び出すだけです。
そして、呼び出される側のクラスの処理は極論を言えば、音楽を演奏したり、Windowsをシャットダウンしたりどのようなことでも書いていいのですが、想像のつかない突飛な処理をすることは望まれておらずヘルプなどのドキュメントに記載されている動作をそれぞれの方法で行おうとします。
Textプロパティで言うと「文字列を表示する」という動作がそれです。
文字列を表示する処理をTextプロパティで統一し、そのTextプロパティの内容は各クラスで実装 を分担する。これがポリモーフィズムです。
上の図ではその両方が表現されています。
なお、ときどき勘違いしている方がいらっしゃいますが、このような構造にしても結局自分で書かなければいけないプログラムの量に変わりはありません。どこにプログラムを書くかという点がかわるだけです。
オブジェクト指向の考え方に基づいて、プログラムの総量を減らすことはできますが、それはこの構造のためではありません。
さて、Textプロパティの例ですが、「文字列を表示する処理をTextプロパティで統一する」と言葉では簡単に書けますが、ここでいうTextプロパティとは単に名前が「Text」であるプロパティではありません。
ここで言うTextプロパティとは以下のように定義されているものです。
名前 | Text |
引数の型 | String |
■表2:Textプロパティのシグネチャ
プロパティには引数がないものもありますが、内部的にはプロパティはメソッドの一種であり、プロパティの型はその内部メソッドの引数の型になります。ですのでこの表ではTextプロパティの型を「引数の型」と表現しています。
もし、Integer型で名前がTextというプロパティがあっても、それは今まで説明してきたTextプロパティではありません。
メソッド・プロパティの名前と引数の型の組み合わせを「シグネチャ」と呼びます。
ですから、さきほどから何度も出てきている「Textプロパティで統一する」の「Textプロパティ」とは上の表のシグネチャのことを指しています。
今後シグネチャを表示するときは表ではなくText(String)のように表記します。名前の後ろにかっこをつけてその中に順番に引数の型を書きます。引数が複数ある場合はカンマで区切ってInvalidate(Rectangle, Boolean)のように記述します。引数がない場合にはRefresh()のようにかっこの中を空にします。
この表記法ではプロパティの型は第一引数として扱います。プロパティに引数がある場合は第2引数以降に記述します。
コントロールは種類が異なっていても文字列の表示以外にもさまざまな共通した振舞いがあります。たとえば、コントロールをアクティブにしたり、コントロールを非表示にしたり、位置や大きさ・背景色なども共通の振舞いです。
今、わかりやすいようにここで例として挙げた振舞いのシグネチャを表に挙げてみます。
振舞い | シグネチャ |
文字列の表示 | Text(String) |
アクティブにする | Select() |
非表示にする | Hide() |
位置 | Location(Point) |
大きさ | Size(Size) |
背景色 | BackColor(Color) |
■表3:振舞いとシグネチャの例
コントロールであればみなこのシグネチャを共有しています。だからこそ便利にポリモーフィズムが活用できるわけです。
もちろん、共有していないシグネチャもあります。たとえば、TreeViewコントロールにはNodesプロパティがありますが、このプロパティのシグネチャは他のコントロールにはない独特なものです。コントロールによって機能は異なりますから共通しているものもあれば共通していないものもあるのは当然でしょう。
ここでは共通しているシグネチャについて考えてみます。
共通しているシグネチャは無数にあって、上記の表で示しているものはほんの一例です。
こうなってくるとポリモーフィズムの観点ではシグネチャを単体であつかうよりもシグネチャセットとしてまとまりを扱った方が簡単でわかりやすくなります。
そこで、人類はこのシグネチャのまとまりを管理する方法をあみだしました。「継承」と「インターフェース」がそれです。
コントロールの例ではTextBoxやLabel、Buttonなどの共通の機能はControlクラスによって定義されており、各コントロール は直接または間接にControlクラスを継承することでシグネチャセットを共有します。
ただし、コントロールの中にはControlクラスで定義されていない、また別のシグネチャセットを共有しているものもありコントロールのポリモーフィズムがすべてControlの継承によって成立しているものではありません。
継承とインターフェースはVBで用意されているシグネチャセットを共有する唯二の機能です。
このうち継承の方はシグネチャセットの共有以外にも便利で重要な機能がありポリモーフィズムとはまた別の意味でオブジェクト指向の三大要素の1つに数えられています。継承の説明は別の機会にします。
ここでは継承によって実現されている主なポリモーフィズムの例を紹介しておきます。
シグネチャセット | クラス |
コントロールの基本共通機能 | Control |
ファイル・フォルダの基本共通機能 | FileSystemInfo |
塗りつぶしの基本共通機能 | Brush |
全オブジェクトの基本共通機能 | Object |
■表4:シグネチャセットの例
とても重要なのはすべてのクラス・構造体がObjectクラスを継承している点です。そのためObjectクラスで定義されているシグネチャセットはすべてのクラスで共有されています。たとえば、どのクラスでも必ずクラスを文字列で表現するためのToStringメソッドが使用できるようになっています。
インターフェースはシグネチャセットの共有だけが目的の機能で、まさにポリモーフィズムを実現するためだけの存在です。
はじめて正面からオブジェクト指向を勉強しようと言う方はインターフェースという言葉を聞いたこともないという人も多いかもしれませんが、実は随所で使用されている便利なものです。
ここまではControlクラスの継承によるポリモーフィズムの例を説明してきましたが、ここからはインターフェースによるポリモーフィズムを説明します。
次のコードはインターフェースを利用したポリモーフィズムのサンプルです。フォームにButtonを2つ貼り付けてから試してください。
Private Sub
Button1_Click(ByVal sender
As System.Object,
ByVal e As System.EventArgs)
Handles Button1.Click Dim Ar As New List(Of String) '平安時代の関白(一部) Ar.Add("藤原基経") Ar.Add("藤原忠平") Ar.Add("藤原実頼") Call ShowCount(Ar) End Sub |
Private Sub Button2_Click(ByVal
sender As System.Object,
ByVal e As
System.EventArgs) Handles Button2.Click Dim Hash As New Hashtable '発明品と発明者 Hash.Add("蒸気機関", "アレクサンドリアのヘロン") Hash.Add("飛行機", "ライト兄弟") Hash.Add("電球", "J.W.スワン") Hash.Add("電話", "グラハム・ベル") Call ShowCount(Hash) End Sub |
Private
Sub ShowCount(ByVal
Ar As ICollection) MsgBox(Ar.Count) End Sub |
■リスト2:インターフェースの使用
この例ではButton1をクリックするとListクラスによるコレクションを生成し、その要素の数を表示します。Button2をクリックするとHashtableクラスによるコレクションを生成し、その要素の数を表示します。実用性はなく完全に説明用です。
さて、どの部分がポリモーフィズムに基づいているかわかりますか?
ShowCountメソッドによってコレクションの要素の数を表示する部分でポリモーフィズムが活用されています。ShowCountメソッドの引数がICollection型になっているのに注目してください。ICollection型で宣言しておくとListクラスでもHashtableクラスでもセットできるようになります。
このICollectionこそがインターフェースなのです。
プログラム内でのインターフェースは普通のクラスのように扱うことができますが、インスタンスを生成することはできません。さきほど説明したようにインターフェースはシグネチャのセットだけを定義したものであって、内容はないのですからインスタンスの生成などありえないのです。仮にインスタンスを生成できるようにしたとしても、そのメソッドを呼び出しても何も起こらないオブジェクトになってしまいます。
インターフェースと普通のクラスはプログラム内では一見したところ区別がつかない危険性が考えられたため、インターフェースの名前は必ず大文字の I からはじまるようにするという決まりがあります。IXxxxという名前を見たらインターフェースの可能性が大きいです。もっとも普通のクラスや構造体の中にもIntegerやImageなどのように I からはじまるものもあるので名前だけで完全に区別できるわけではありませんが、慣れてくれば問題なく見分けられるようになります。
ICollectionインターフェースで定義されているシグネチャは以下の通りです。
シグネチャ | 機能(振舞い) |
Count | 要素の数を取得する。 |
IsSynchronized | アクセスが同期されているか調べる。 |
SyncRoot | アクセスを同期するために使用できるオブジェクトを取得する。 |
CopyTo | コレクションの内容を配列にコピーする。 |
■表5:ICollectionインターフェース
この情報はヘルプにもっと詳しく記載されています。
ListクラスもHashtableクラスもICollectionインターフェースを実装しているので、この4つのメソッド・プロパティ(=シグネチャ)が使用可能であると言うわけです。
なお、インターフェースは単にシグネチャを定義しているだけでその振舞いまでは定義していません。Countプロパティを呼び出したときに何が起きるかはListクラスやHashtableクラスなど各クラスの側で定義されています。
ListクラスとHashtableクラスは共通して継承しているクラスはObjectクラス以外存在しないので、TextBoxクラスとCombobBoxクラスのときのControlクラスに該当するようなクラスが存在せず、継承を利用したポリモーフィズムは利用できません。
■図3:実際にはControlクラスは間接的に継承されている。
ListクラスとHashtableクラスはICollection以外にもさまざまなインターフェースを実装しています。以下はこれらのクラスが実装しているインターフェースの一覧です。
Listクラスが実装するインターフェース
※単純化のためにジェネリックは省略しています。 |
Hashtableクラスが実装するインターフェース
|
■表6:インターフェースの比較
表を見るとわかるようにいくつかのインターフェースは共有していますが、それぞれが独自に実装しているインターフェースもあります。
これを図に表すと次の通りです。
■図4:ListクラスとHashtableクラスが実装するインターフェース。一部割愛。
今回使用しているICollectionインターフェースだけ色を変えて目立たせておきました。図が大きくなってしまうのでいくつかのインターフェースは省略しています。
継承を利用している場合、継承元のクラスは1つだけなのですが、インターフェースの場合はこのようにいくつでもインターフェースを実装することができます。
インターフェースも使用例をもう1つ紹介しましょう。
以下の例を実行するにはさきほどと同じようにButtonを2つ用意してください。
Dim
MainList As New
ArrayList Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '鎌倉時代の関白(一部) MainList.Add("九条兼実") MainList.Add("一条実経") End Sub |
Private Sub Button1_Click(ByVal
sender As System.Object,
ByVal e As
System.EventArgs) Handles Button1.Click Dim Ar As New List(Of String) '平安時代の関白(一部) Ar.Add("藤原基経") Ar.Add("藤原忠平") Ar.Add("藤原実頼") MainList.AddRange(Ar) End Sub |
Private
Sub Button2_Click(ByVal
sender As System.Object,
ByVal e As
System.EventArgs) Handles Button2.Click Dim Hash As New Hashtable '発明品と発明者 Hash.Add("蒸気機関", "アレクサンドリアのヘロン") Hash.Add("飛行機", "ライト兄弟") Hash.Add("電球", "J.W.スワン") Hash.Add("電話", "グラハム・ベル") MainList.AddRange(Hash) End Sub |
■リスト3:インターフェースの使用
この例ではArrayListクラスのAddRangeメソッドが引数にICollectionを採ることを利用しています。ListクラスもHashtableクラスもICollectionインターフェースを実装しているのでAddRangeメソッドの引数に渡すことができると言うわけです。
この例ではAddRangeメソッドの内部がわからないので、なぜICollectionが必要とされているのかわかりません。AddRangeメソッドを作ったプログラマはとにかくICollectionで定義されている機能があればAddRangeメソッドを実装できるようにしたということがわかるのみです。
長々と説明してきましたが、それで結局ポリモーフィズムとは何がどう便利なのでしょうか?ここまでのことを少し視点を変えてみてみます。
インターフェースを共有するクラスAとクラスBがあるとします。
プログラムは引数でインターフェースを受け取ってこのインターフェースのメソッドを呼び出して1つの機能を実装しています。イメージとしては次のような感じです。
Public Sub
DoAnything(Obj As IShare) If Obj.Method1 Then Obj.Method2 End If End Sub |
■リスト4:ポリモーフィズム的呼び出し
このような構造がポリモーフィズムの考え方に基づいていることはもう説明の必要はないでしょう。
それで、このような構造にすると何がどう便利なのでしょうか?
このメソッドでは引数Objに実際にはクラスAがわたされるのかクラスBがわたされるのかわかりません。わからなくても問題ないようになっています。
たとえば、呼び出し側は次のようなっているかもしれません。
Dim A
As New ClassA DoAnything(A) |
■リスト5:クラスAの生成と呼び出し
あるいは、次のようになっているかもしれません。
Dim B
As New ClassB DoAnything(B) |
■リスト6:クラスBの生成と呼び出し。リスト5とリスト6がまったく等価であり交換可能であることが重要。
またはその両方かもしれません。
つまり、クラスAとクラスBは完全に同じ立場に立っており、構文上は何の区別もありません。この状態のとき、構文上2つのクラスをお互いに入れ替えても問題ありませんので、この状態を「交換可能である」と呼ぶことにします。
この「交換可能である」という性質、つまり交換可能性こそがポリモーフィズムを便利たらしめているものなのです。
このような考え方に立つと、各クラスの側ではそれぞれの個別の機能だけを定義すればいいことになります。そして、それらの機能を組み合わせてまとまった意味のある機能にするのがDoAnythingメソッドになるわけです。
1つのインターフェースをデザインすれば、他の同種の機能もそのインターフェースを実装してプロうグラムするだけでよくなります。
細かいことはDoAnythingメソッドが面倒を見てくれます。
話が少し抽象的でわかりにくかったかもしれません。具体例は次回以降に登場する予定です。
ここまででポリモーフィズムという考え方および、それを実現する手段としての継承、インターフェースについて説明しました。
実際にポリモーフィズムを「便利」と言えるくらいに活用するにはまだまだ説明しなくてはいけないことがありますが、概要としては以上で完結です。
継承やインターフェースという考え方はVB以外にもC#やJavaなどでも共通している考え方で、やはりポリモーフィズムの実現のために活用されます。
ところが、VBではもう1つポリモーフィズムを実現する強力な機能があるのです。それが「実行時バインディング」です。
これは使い方は継承やポリモーフィズムよりもはるかに簡単で、初心者は無意識に使っています。
以下は実行時バインディングの例です。
Dim o
As
Object o = Me.GetNextControl(sender, True) If o.Enabled AndAlso o.Visible Then o.Select() End If |
■リスト7:実行時バインディング1
このプログラムは変数oをObject型で定義しています。そして、随所でEnabledやVisible、SelectなどObject型では定義されていないメソッドやプロパティを呼び出しています。
これはoが実際にControlであるのか、ArrayListであるのかその他のクラスあるのかの判断を実行時まで保留するという意味があります。
このプログラムが実行されるときになってはじめてEnabledプロパティが存在するのかの判定が行われ存在するならEnabledプロパティが呼び出され、存在しないならばエラーになります。
つまり、Object型などの汎用型で定義しておけば好きなメソッドやプロパティがどんどん呼び出せてしまうのです。継承やインターフェースではあらかじめ用意しておいたシグネチャのセットに従って呼び出しが行われますが、実行時バインディングではそのようなものをあらかじめ用意する必要はありません。
これは非常に便利な機能です…が、便利すぎて危険です。
たとえば、メソッドやプロパティのスペルを間違っても実行するまでそのことに気が付きません。通常はビルド時にチェックが行われるのでスペルミスがあるまま実行すると言うことはあり得ませんが、実行時バインディングでは実行時にメソッドやプロパティを探すためいざ実行するまで正しいか正しくないか判断できません。
それに、実行時にメソッドやプロパティを探すと言う余計な処理が必要になるので動作がその分遅くなります。ちょっとシビアなアプリケーションなら我慢できなくらい遅くなります。
実行時バインディングは便利な機能ではありますが、使いどころをよく考えてプログラムの癌にならないように気をつけて使用しましょう。
私は別に実行時バインディング反対派ではありませんが、世の中には実行時バインディングの使用を禁止している方々もいらっしゃいます。
Option StrictをOnにすると実行時バインディングは使用不可になり、プログラムの堅牢性が向上します。
最後に、もう1つ実行時バインディングの単純な例を紹介しておきます。こういう書き方ができるって楽でいいですよね。
Private
Sub Button1_Click(ByVal
sender As System.Object,
ByVal e As
System.EventArgs) Handles Button1.Click sender.Text = "こんにちは!" End Sub |
■リスト8:実行時バインディング2
発展学習では意欲的な方のために現段階では特に理解する必要はない項目を解説します。 もっと構造化された実行時バインディングとして「リフレクション」という仕組みが用意されています。リフレクションはOption Strict Onのときでも使用可能ですが、上述の実行時バインディングの例と同じ危険があります。 リフレクションの機能を使用するにはSystem.Reflection名前空間のクラスを使用します。特にTypeクラスはリフレクションの中心です。Objectクラスが実装しているGetTypeメソッドや、名前が同じで紛らわしいVBのGetTypeメソッドを使用するとTypeクラスのインスタンスを取得できます。 VBではもっと気軽にリフレクションを利用するためにCallByNameという関数が用意されています。 |
ポリモーフィズムとは「同じ振舞いをするオブジェクトは同じように呼び出せるようにすべきである」という考え方のことです。
ポリモーフィズムの考え方に基づいてプログラムすると以下のメリットがあります。
ポリモーフィズムは同じシグネチャのメソッドやプロパティを統一的な手法で呼び出せるようにすることで実現します。
通常は複数のシグネチャの組み合わせをいろいろなクラスで共有することが多いので、単独のシグネチャよりもシグネチャのセットに着目します。
ポリモーフィズムを実現するために、VBでは以下の機能があります。これらの機能はすべてシグネチャまたはシグネチャセットを共有する方法でもあります。
ポリモーフィズムを便利に使いこなすためには、さらなる知識と訓練が必要です。知識面においては次回以降に説明します。訓練についてもある程度はサポートしますがやはり自分でプログラムを構築してみることが一番でしょう。
最後にいくつか注意しておきます。
ポリモーフィズムのメリットとしてあげた「統一性」、「交換可能性」、「実装の分担」は私が言っているだけで、ほかの研究者や実務家のあいだで定説となっているわけではありません。同じようなことを違う言葉で説明している方もいらっしゃいますし、観点が少し違う方もいらっしゃるようです。
ポリモーフィズムについては定説と呼べる説明がないようでしたので独自用語および独自研究を展開しました。それほどはずしていないとは思いますが、このことも念頭においておいてください。ただし、研究者や実務家の間ではポリモーフィズムとは○○であるという認識はほぼ一致しています。この「○○」を初学者向けに言葉で表現することについて定説がない状況というわけです。
それから、シグネチャのまとまりのことを「シグネチャセット」と表現しているのも多分私だけです。
次回からは自作のクラスにインターフェースを実装する方法およびインタフェースを自作する方法を説明します。継承についてはその後で扱います。