|
|
連載:VB 6ユーザーのための これならマスターできるVB 2005超入門
第9回 そろそろまじめにクラスに取り組んでみようか
羽山 博
2007/06/06 |
 |
|
■クラスからオブジェクトを作成する
さて、お待ちかねのオブジェクト作成だ。ここまででクラスを定義したが、クラスとはあくまでもひな型のようなもの。Monsterクラスは、個々のモンスターを表すのではなく「モンスターってこんなものだよ」という形を表しているだけだ。だから、クラスから個々の実体を作る必要がある。この実体のことをオブジェクトとかインスタンスと呼ぶ、というのはすでにお話ししたとおり。
このプログラムでは、[モンスター作成]ボタンをクリックしたときに、Monsterクラスのオブジェクトを作るので、ボタンのClickイベント・ハンドラにそのためのコードを書けばよい。先にそのコードを見てみよう。
Public Class Form1
Private Sub makeOne(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMake.Click
Dim m As Monster
m = New Monster()
MessageBox.Show(m.Name & ":" & m.Hp)
End Sub
End Class
|
|
Monsterクラスのオブジェクトを作成する |
クラスのオブジェクトを参照する変数mを宣言し、Newキーワードを指定してオブジェクトを作成する。オブジェクトが作成されると、その参照が返されるので、mに代入する。変数mを使えば、オブジェクトのプロパティやメソッドが利用できる。 |
最初の宣言にまず注目しよう。Monsterクラスのオブジェクトを参照する変数mを宣言していることが分かる。ここで重要なのは、変数mが値型ではなく参照型であるということ。念のため図で表すと、図5のようになる。

|
図5 Monsterクラスのオブジェクトを参照する変数を宣言した |
変数mには値が入るのではなく、Monsterクラスのオブジェクトへの参照が入れられる。ただし、この段階では変数が宣言されただけ。オブジェクトはまだ作られていないし、参照も代入されていない。 |
この図5で、矢印やMonsterクラスのオブジェクトを点線で示したのは、まだオブジェクトは作られていないし、参照も代入されていない(が、後でオブジェクトが作られ、参照が代入されたらこのようになる)ということを表すためだ。
コードの続きを見てみよう。次は、
となっている。このように、Newキーワードを指定すれば、クラスのオブジェクトを作成することができる。つまり、右辺の「New Monster()」で、オブジェクトが作成される。このとき、作成されたオブジェクトへの参照が返されるので、それを左辺に代入すれば、オブジェクトへの参照がmに代入される(図6)。

|
図6 Monsterクラスのオブジェクトを作成し、参照を変数に代入した |
Newキーワードを指定して新しいオブジェクトを作成し、その参照をmに代入する。これで、mを利用してMonsterクラスのオブジェクトにアクセスできるようになる。 |
この図では「参照」という個所の矢印に注意。Monsterクラスのオブジェクトの参照がmに代入されると、mを使ってオブジェクトが扱える、という意味で右向きの矢印を描いてある。mの内容がMonsterクラスのオブジェクトに代入されるという意味ではない。念のため(値型と参照型の説明をもう一度見てみよう)。
なお、オブジェクトを参照する変数の宣言と、オブジェクトの作成をまとめて、
Dim m As Monster = New Monster()
|
|
と記述でき、さらに短縮して、
と記述することもできる。
ともあれ、これでMonsterクラスのオブジェクトが作成できた。あとは、プロパティやメソッドを利用すればよい。例えば、
MessageBox.Show(m.Name & ":" & m.Hp)
|
|
とすれば、作成したオブジェクトのNameプロパティの値とHpプロパティの値がメッセージ・ボックスで表示される。
■どのオブジェクトでも共通に使えるプロシージャを作る
このMonsterクラスからは、個々のオブジェクトをいくつでも作ることができる。ところが、どのオブジェクトからでも共通に使えるプロシージャ(メソッド)が必要になることもある。例えば、2匹のモンスターの生命力を比較するメソッドを作りたい場合などがそれに当たる。
そんなときに使えるのが「Shared」というキーワードだ(Sharedは「共有された」という意味)。プロシージャの定義にSharedキーワードを付けると、それぞれのオブジェクトではなく、クラスで共通に使えるプロシージャとなる。2匹のモンスターのHPを比較するFunctionプロシージャは次のように書ける。
Public Shared Function Compare(ByVal x As Monster, ByVal y As Monster) As Integer
If (x.Hp() = y.Hp()) Then
Return 0
ElseIf (x.Hp() < y.Hp()) Then
Return -1
Else
Return 1
End If
End Function
|
|
クラスで共通に使えるプロシージャを定義する |
プロシージャの定義にSharedキーワードを付けると、クラスで共通に使えるプロシージャになる。 |
ここで作ったCompareメソッドは、2匹のモンスターの生命力が等しければ0を返し、最初の引数に指定したモンスターの生命力の方が小さければ-1を、最初の引数に指定したモンスターの生命力の方が大きければ1を返す。このようなメソッドは、それぞれのオブジェクトを参照する変数を使うのではなく、クラス名を使って呼び出すことができる。つまり、
Dim m1 As New Monster()
Dim m2 As New Monster()
|
|
と宣言しても、m1やm2を使わずに
m1.Hp = 30
m2.Hp = 40
MessageBox.Show(Monster.Compare(m1, m2))
|
|
のように、Monster.Compare(……)と書ける。この場合だと、メッセージ・ボックスには「-1」と表示されることになる。なお、m1.Compare(m1, m2)やm2.Compare(m1, m2)のように、オブジェクト名を使っても同じ結果は得られるが、コードの意味が分かりにくくなるので、そのような書き方は避けた方がいい(エラー一覧にも警告のメッセージが表示される)。
もっとも、この例は単純すぎるので、m1.Hpとm2.HpをIfステートメントで比較演算子(「>」や「<」など)を使って比較した方が簡単だが、比較の方法が複雑になるような場合には、こういうメソッドを作っておくと便利だ。例えば、Stringクラスにも文字列の大小を比較するCompareという名前のメソッドがあるが、大文字と小文字を区別しないで比較したり、並べ替え規則を指定して比較したりするなど、単純な比較演算子だけではできないような比較ができるようになっている。