Visual Basic 中級講座
VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応 VB2008 対応

 

Visual Basic 中学校 > 中級講座 >

第1回 オブジェクト指向へようこそ

 

オブジェクト指向の考え方を説明します。オブジェクト、カプセル化、ポリモーフィズム、継承という重要な考え方が登場します。

概要

・ オブジェクト指向とは現実に存在する「物」に似せてプログラムを行い、「物」同士を連携させてシステム・アプリケーションを構築していくスタンスのこと。

→この「物」のことを「オブジェクト」と呼び、VBではクラスとして表現される。

・オブジェクトにはデータと振舞いがある。

データとはフィールド(変数・定数)のことで、振舞いはメソッドのことである。プロパティはフィールドにアクセスするメソッドである。

・オブジェクトは内部の詳細を隠して外部に対しては使用方法と結果だけを定義すべきである。これをカプセル化という。

・同じ振舞いをするオブジェクトは同じように呼び出せるようにすべきである。これをポリモーフィズムという。

・継承とは既に存在するオブジェクトの振舞いを引き継いだ新しいオブジェクトを作成することである。

※この記事は2007/11/18に全面的に改訂しました。改定前の記事はこちらをご覧ください。

1.オブジェクト同士の連携

 

オブジェクト指向プログラミングとはプログラムの作り方のスタンスで、次のような特徴があります。

ここで重要なのは「現実世界のものをモデル化する」という発想です。プログラムやコンピュータに独特の発想をしてシステムを構築するのではなく、人間が理解・認識して発展させていくことが容易になるように現実世界をモデルにするのです。

具体的な例をあげましょう。以下の図はある会社で社長がパソコンを購入する様子を簡単にモデル化したものです。

■画像1:社員同士が連携してパソコンを購入する

この図を簡単に説明すると、社長は社員1に対して「@パソコンを買おう」と提案をします。社員1はそれに基づいてパソコンのピックアップを依頼したり、業者に見積もりをしてもらったりして、最終的には「Gどうぞ!」と社長にパソコンを届けます。

ここで注目してもらいたいのは社長だけを見た場合、「@パソコンを買おう」と提案をすると、「Gどうぞ!」という結果が返ってきていることです。社長はどのようなプロセスでパソコンが購入されたのか知る必要はありませんし、知らなくてもパソコンが手に入るのです。

同様に今度は社員2だけに注目してみましょう。

■画像2:社員2

社員2は「Aピックアップしてくれ」という依頼が来たら、「Bピックアップしました」という結果を返すだけです。社員2は実際にはカタログを見たり、インターネットで調べたりして購入すべきパソコンをピックアップしたのでしょうが、他の社員や社長はそのようなプロセスを知る必要はありませんし、知らなくてもちゃんと最終的には社長のもとにパソコンが届きます。

このように、現実のプロセスをモデル化してみると個々の要素は独立しており、かつ、要素同士が連携しあって1つの目的が達成される様子がわかります。これと同じようにしてプログラムを仕組んでいくのがオブジェクト指向です。

具体例を示すために上記の流れをそのままプログラム化してみると次のようになります。全体的な雰囲気だけ見てもらいたいので左右2つに分割してできるだけスクロールなしで全部が見られるようにしました。最初の図と見比べてください。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応
Public Class 社長

  Public
Sub パソコンを欲しがる()
    Dim Computer As パソコン
    Computer = 社員1.パソコンを買う
  End
Sub

End
Class

■社長クラス

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Public Class 社員1

  Public
Shared Function パソコンを買う() As パソコン

   
'▼ピックアップ
   
Dim Computer As パソコン
    Computer = 社員2.パソコンをピックアップする

   
'▼見積
   
Dim Estimate As 見積
    Estimate = 販売業者.見積する(Computer)

   
'▼購入
   
Return 販売業者.販売する(Estimate)

  End
Function

End
Class

■社員1クラス

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応
Public Class 社員2

  Public
Shared Function パソコンをピックアップする() As パソコン

    Return New パソコン

  End
Function

End
Class

■社員2クラス

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Public Class 販売業者

  '''
<summary>パソコンを見積する。
</summary>
 
Public Shared Function 見積する(ByVal Computer As パソコン) As 見積

    Return New 見積(Computer, 210000)

  End
Function

 
Public Shared Function 販売する(ByVal Order As 見積) As パソコン

    Return Order.パソコン

  End
Function

End
Class

■販売業者クラス

■リスト1

これは単純に最初の図をプログラム化しただけのものなのでプログラミングのお手本となるようなものではありません。いくら現実世界のものをモデル化してプログラムすると言っても実際にはやはりコンピュータやプログラムの世界に独特の考え方も必要になってきます。

しかし、オブジェクト指向がどのような発想であるかと言う点は、最初の図とこのプログラムを見比べていただければイメージしていただけるのではないでしょうか?

 

2.オブジェクト

 

現実世界の「もの」をモデル化していくオブジェクト指向ですが、この「もの」のことを「オブジェクト」と言います。ですから、先ほどの例では社長や社員1、社員2、販売業者などがオブジェクトです。

オブジェクトの性質として重要なのはオブジェクトには「振舞い」(読み方:振舞い = ふるまい)があるという点です。

最初の例を基に各オブジェクトの振舞いを抜き出してみると次のようになります。

社長
パソコンを欲しがる

 

社員1
パソコンを買う
社員2
パソコンをピックアップする

 

販売業者
見積もりする
販売する

図を見ればすぐにわかるのですが、各オブジェクトはこの振舞いを使用して連携しています。ですから「もの同士が連携して動作する」というオブジェクト指向の発想上振舞いはなくてはならないものです。

さらに、オブジェクトのもう1つの性質を挙げると、オブジェクトには「データ」があります。

たとえば、社員2はパソコンをピックアップするときにカタログなどの何らかのデータを参考にしているはずです。また、販売業者は当然パソコンの原価や在庫などのデータを持っており、それを基に見積もりをしているはずです。

ただし、振舞いと違ってデータはオブジェクト同士の連携には直接関係しませんし、ひょっとすると社長のように何のデータも持っていないかもしれないオブジェクトもありえます。また、データは外部には公開されておらずそのオブジェクトの内部でだけ使用されているのも特徴です。

もっとも実際のVBのプログラムではデータ自体を外部に公開することもありますが、そのようなオブジェクトはかなり少数派です。

 

ここまでの内容を実際のVBのプログラムに置き換えて考えてみましょう。

オブジェクトとはクラスやそのインスタンスのことになります。オブジェクト同士が連携するための振舞いとはメソッドやプロパティのことです。オブジェクトが内部に持っているデータとは変数のことです。ただし、このような視点に立つとき変数のことを「フィールド」と呼びますので覚えておいてください。

オブジェクト指向の考え方 実際のVB
オブジェクト クラス、インスタンス
振舞い メソッド、プロパティ
データ フィールド(変数)

 

3.交換可能性

 

さて、オブジェクト指向の発想にたってプログラムする場合、何がどのように優れているのでしょうか?もちろん、この答えは簡単には説明できないので、今後数回にわたって説明していくことになりますが、根本的な発想の1つである交換可能性についてはあらかじめ説明しておくことにします。

交換可能性はオブジェクト指向プログラミングの最大のメリットで、オブジェクト指向について考えるときはこの性質を意識するようにすると理解が深まります。

交換可能性とは「同じ振舞いをするオブジェクト同士は交換可能である」という性質のことです。

たとえば、先ほどの社員2にもう一度登場してもらいます。

■画像3:社員2の振舞い

社員2の振舞いは「パソコンをピックアップすること」です。ですから、同じようにパソコンをピックアップすることができるものであれば社員2と入れ替えることができるというのが交換可能性です。

仮に次のようにパソコンをピックアップすることができる社員3が存在するとしましょう。

■画像4:社員3の振舞い

そうすると、最初の図の社員2のところには、社員2と交換して社員3を当てはめることができるわけです。

■画像5:社員2の代わりに社員3を当てはめる

このとき、社員2と社員3はどちらもパソコンをピックアップして結果を返してくれますが、ピックアップする方法は違うかもしれませんし、ピックアップのために使用しているカタログなどのデータも異なるかもしれません。それに、ひょっとするとピックアップの結果も異なるかもしれません。

でも、そこがメリットになるのです。つまり振舞いさえ統一しておけば、異なる動作をさせることも可能なのです。 逆にまったく同じ動作をする社員であれば交換する意味はありません。(本当に人間であれば疲れたので交代すると言う意味はありますが)。

交換可能であると言うことの背景には、異なる機能を実現するためには振舞いが統一された別のオブジェクトを用意するだけでよいと言う意味があります。

たとえば、最近はやりのゲーム機を考えてみても、ゲーム機本体は同じものを使っていてもソフト(DVDやROM)を交換するだけで違うゲームを遊ぶことができます。これは交換可能なソフトを利用して異なる実現しているわけです。違うゲームをやるためにはゲーム機ごと買い替えなければいけない場合と比較すると交換可能であることのメリットは十分理解していただけるでしょう。

博士のワンポイントレッスン
V太 V太:なんかゲームにたとえると急にわかった気になりますね。交換可能性は重要です!
博士 博士: まぁ身近なものに置き換えると言うのはたいていの場合わかりやすい説明ではあるの。じゃが、オブジェクト指向の話をしている場合はこれが単なるたとえ話ではないということに注意してほしい。
V太 …と言いますと?
博士 ゲームの例はオブジェクト指向のたとえ話ではなく、オブジェクト指向そのものなのじゃ。その前にでてきた社員が連携してパソコンを買う例も単なるたとえ話ではなくオブジェクト指向そのものなのじゃ。この発想をプログラムの世界での生かしていくのがオブジェクト指向プログラミングなのじゃ。

 

交換可能であることがプログラム上でどのようなメリットになるのかをはっきりさせるために、具体的なプログラムを考えてみます。

みなさんも是非、実際に動かしながら説明を読んでください。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

    Dim
MyBrush As Brush = GetBrush()
    e.Graphics.FillEllipse(MyBrush, 10, 10, 200, 200)

End
Sub

Private Function GetBrush() As Brush

    Return
New SolidBrush(Color.Blue)

End
Function

■リスト2

このプログラムを実行すると、次のように青い円が表示されます。

■画像6

さて、このプログラムを次のように改造してみてください。わかりやすいように変更する個所には色をつけておきました。

VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

    Dim
MyBrush As Brush = GetBrush()
    e.Graphics.FillEllipse(MyBrush, 10, 10, 200, 200)

End
Sub

Private Function GetBrush() As Brush

    Return
New TextureBrush(New Bitmap("C:\Windows\隅田川.bmp"))

End
Function

■リスト3

画像ファイルはパソコン上に存在するものに適宜置き換えてください。C:\Windows\隅田川.bmpならたいていのパソコンに最初から入っていると思うので、とりあえずこのまま実行してみるのがよいでしょう。

今度は結果は次の通りになります。

■画像7

最初のプログラムでは円を描くのにSolidBrushクラスを使用していました。2番目の例ではSolidBrushを生成する個所を変更してTextureBrushクラスが生成されるようにしました。

このときに円を描画する部分のプログラムは一切変更していない点に注意してください。変更したのはブラシを生成するGetBrushメソッドだけです。

このようなプログラム変更が可能なのはSolidBrushクラスとTextureBrushクラス が交換可能であるからです。もし、この2つのクラスがまったく異なる振舞いを持っているのならば実際に円を描画する部分も変更する必要があったでしょう。

このことが意味しているのは事前に計画された振舞いに基づいてプログラムを構築しておけば、後でオブジェクトを入れ替えるだけで違った動作をさせることができるということです。

もっと業務に即した例で考えると、たとえば、データベースへの接続するプログラムではSQL Server用に書いたものが、オブジェクトを入れ替えるだけでOracleに対しても使用できる可能性があることを示しています。

また、社員テーブルをテキストファイルに書きだす処理は売上テーブルに対しても使用可能である可能性も示しています。

交換可能性とはさまざまなシーンでプログラム作成作業を省力化し、プログラムの拡張性をも圧倒的に向上させるすぐれた考え方なのです。

 

もう1つシンプルな例を紹介しましょう。

VB6対応 VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応


Control1.Text = "こんにちは"
 

■リスト4

このプログラムはControl1と名付けられたオブジェクトに「こんにちは」という文字列を設定するものですが、Control1TextBoxでもLabelでもButtonでも、その他の コントロールでも動作します。もちろん、Textプロパティと言う振舞いを持っていると言う条件は必要ですが、この振舞いを持っているオブジェクト同士はこのプログラムにおいては交換可能なのです。

 

この交換可能性は「同じ振舞いをするオブジェクトは同じように呼び出せるようにすべきである」という考え方に由来しており、この考え方はポリモーフィズムと呼ばれます。日本語では「多態性」と呼びます。

ポリモーフィズムの発想に立って設計・プログラムができるようになればオブジェクト指向プログラミングはマスターしたといってもいいでしょう。ポリモーフィズムおよび交換可能性の詳細はこの講座でも詳しく取り上げていく予定です。

 

4.オブジェクト指向の要素

 

4−1.オブジェクト

最後にまとめとしてオブジェクト指向プログラミングがどのような要素から成り立っているか考えてみます。

既に説明したようにオブジェクト指向では、「振舞い」と「データ」を持ったオブジェクトが必要です。これが最も基本的な部分です。VBでは初代のVB1の時点で既にこの要素が実装されていました。

 

4−2.カプセル化(隠蔽)

振舞いは単にオブジェクトに作業をさせるための窓口と言うだけではなく、オブジェクトの機能が簡単に呼び出せるようになっている必要があります。そうでなければオブジェクト同士の連携が困難になりますし、プログラムもいたずらに複雑になるからです。

オブジェクトの機能を簡単に呼び出せるようにするために、「振舞い」は単独で必要なすべての処理を行う必要があります。メソッドAを呼び出すためには、その前にまずメソッドBを呼び出さなければいけないというのはナンセンスです。メソッドAの機能が必要な場合はメソッドAだけを呼び出せばよいようにするのが最も簡単な呼び出し方法でしょう。このように振舞いの内部に必要な処理をすべて詰め込むことを「カプセル化」と呼びます。

もっともオブジェクトの設計次第ではメソッドごとに役割が分割され、呼び出す順番が重要になる場合があるので、必ずしも1つの機能のために複数のメソッドを呼び出すことが悪いと言うことにはなりません。この場合は、1つの役割を果たすためには1つのメソッドを呼び出せばよいようになっていればカプセル化されていることになります。

カプセル化のことを「隠蔽(いんぺい)」と呼ぶ場合もあります。これはメソッドによって、内部の処理が隠されている、つまり隠蔽されているためです。

博士のワンポイントレッスン
V太 V太:博士。これはゲームにたとえるとどう言うことになりますか?
博士 博士: むむむ…、そうじゃのう。ゲームで遊ぶ時にはゲームのプログラムを知らなくてもいいと言うことかのぉ?Aボタンを押せばジャンプするし、Bボタンを押せば火を吐く。このとき、AボタンやBボタンのプログラムがどうなっているか知らなくても機能は呼び出せると言うわけじゃ。
B子:Aボタン?Bボタン?火を吐く?
と、とにかく、内部のことがわからなくても「呼び出せば動く」というのが便利なんじゃないかの?プログラムがどうなっているかしらなきゃゲームもできないとなると大変じゃろう?
V太 そりゃ、そうですね。

 

4−3.ポリモーフィズム(多態性)

次にオブジェクト同士を連携させて動作させるためには、オブジェクトの交換可能性が重要であると言うことを説明しました。オブジェクトが交換可能であるためには、ある機能のための振舞いが統一されている必要があります。前述した例で言うとパソコンをピックアップする機能を呼び出すためには「ピックアップしてくれ」と頼めば良いようになっているべきです。人によって異なる頼み方をしなければいけないとするとその人たちは交換可能ではありません。

このように、オブジェクト同士をうまく連携させるために振舞いを統一させることを「ポリモーフィズム」または「多態性(たたいせい)」と呼びます。このことは既に説明しました。

ポリモーフィズムによって実現される交換可能性は、動作が異なるオブジェクトが交換可能になる点に意味があることも押さえておいてください。まったく同じオブジェクトであれば交換する意味がないからです。つまり、交換可能であると言うことの背景には、一部分を置き換えるだけで異なる機能を実現することができるということがあります。

 

4−4.継承

さらに、複数のオブジェクトを考えて、うまく連携が図れるように共通する機能を抽出することでポリモーフィズムを実現しようとする場合があります。このとき、共通する機能だけをあつめた仮想のオブジェクトを想定して、実際に存在する各オブジェクトはその仮想オブジェクトから機能を引き継いでいるものと考えることがしばしばあります。このように考えると仮想オブジェクトが実装している振舞いについては各オブジェクト間でのポリモーフィズムが保障されるからです。この例のようにオブジェクトから機能を引き継ぐことを「継承」と呼びます。

博士のワンポイントレッスン
V太 V太:博士。継承はゲームにたとえるとどう言うことになりますか?
博士:ぐう。なんでもゲームにたとえるというわけには…
B子:こういうことじゃないかしら?ゲームになれている人なら新しい格闘ゲームをやってもすぐにコツをつかむことができるわよね?それは、格闘ゲームには共通した法則みたいなものがあってゲームに慣れている人は自然とその法則が身についているからだと思うの。
V太 たしかにね。格闘ゲームならだいたい似たような画面だし、操作も似てるからね。それで…?
このことを実際には存在しない「一般的格闘ゲーム」がもとになっていると考えるのよ。他の格闘ゲームはこの「一般的格闘ゲーム」から画面・操作性などの機能を引き継いでいる、だから新しい格闘ゲームでもすぐにコツがつかめるんだって風によ。
V太 それとプログラムに何の関係が?
V太はにぶいわねぇ。こう考えれば「一般的格闘ゲーム」を引き継いでいるゲームは交換可能であると言うことになるでしょう?すぐにコツをつかむことができるのは交換可能だからよ。交換不可能なくらい違うゲームならすぐにコツをつかむなんてことはできないでしょう。
ふーむ。一理あるのぉ。ゲームに限らず自動販売機でも電話でも同じことが言えるの。共通している部分をよく知っているからこそ、あたらしい自動販売機や電話でもすぐに使えるのじゃ。また、自動販売機や電話を作る側もすぐに使えるように共通する部分のデザインはできるだけ変えないようにしておる。これを「一般的自動販売機」や「一般的電話」から機能を引き継いでいると考えるのが「継承」じゃ。 そして、継承によって「ポリモーフィズム」が実現されていると言うことも見逃してはいかん。

※記事の最後にも書いてありますが、ここではそれぞれの要素の一面だけをとらえていることに注意してください。継承やポリモーフィズムにはここでは触れていない一面もあります。

 

4−5.まとめ

以上をまとめると、オブジェクト指向に必要な4つの要素は次のようになります。

オブジェクト 振舞いとデータを持ったオブジェクトが存在すること。
カプセル化(隠蔽) 振舞いがその内部でどのような処理を行っているかにかかわらず、呼び出すだけで機能を果たすようになっていること。
ポリモーフィズム(多態性) オブジェクト同士で振舞いを統一することによって、オブジェクト同士がうまく連携できるようにすること。同じ振舞いをするオブジェクトは同じように呼び出せるようにすべきであるとうこと。
継承 オブジェクトから機能を引き継いで新しいオブジェクトを作成することでポリモーフィズムを保証すること。

この4つの中でオブジェクトが存在すると言うことはオブジェクト指向の大前提です。

残りの3つのカプセル化・ポリモーフィズム・継承のことをオブジェクト指向の三大要素と呼ぶ場合があります。

 

ここでは三大要素について簡単に説明しましたが、それぞれの一面にしか言及していないことに注意してください。たとえば、ポリモーフィズムとは無関係に別のオブジェクトの機能を簡単に利用するためだけに継承が使用される場合もあります。詳細は今後数回にわたって説明する予定であり、ここではどんな考え方があるのかを簡単に示しただけです。また、「三大要素」とは便宜的にこう呼ばれているだけで、三大要素=オブジェクト指向とわけではありませんのでご注意ください。