コンストラクタ

 今まで作成したCarクラスは、オブジェクトを生成後に初期化して使用してもらいました。もし、初期化せずに使用するとどうなるのでしょうか?ガソリンが0リッターなので、加速しても走りません。Carクラスには初期化メソッドが用意されており、Carクラスを利用する側が呼び出しの記述をしないと初期化されません。そこで、オブジェクトを生成した時に初期化をするように調整しましょう。そのようなときに利用できる仕組みが「コンストラクタ」です。

 コンストラクタは、クラスからインスタンス生成をする際にフィールド変数に値を設定するなどの初期設定を行う機能です。インスタンス生成を行う際に呼び出される特別なメソッドを記述します。

コンストラクタ定義の書式
アクセス修飾子 Sub New(仮引数リスト)
 フィールドの初期化処理など
End Sub

○ プロジェクト

 プロジェクトを作成して確認してみましょう。

プロジェクトの種類 コンソール アプリケーション
プロジェクト名 ConstractorTest

サンプルダウンロード

○ 作成の準備

 Carクラスにコンストラクタの記述を追加しましょう。「OverloadTest」をコピーしてプロジェクトを作成してください。

○ プログラム

 次のように記述を追加・修正してください。

Car.vb

  1. Public Class Car
  2.  'フィールド==========
  3.  'Public _speed As Integer     'スピード情報
  4.  Private _speed As Integer     'スピード情報(修正)
  5.  'Public _gas As Double      'ガソリン情報
  6.  Private _gas As Double     'ガソリン情報(修正)
  7.  'コンストラクタ===========
  8.  Public Sub New()
  9.   Me.New(20)
  10.  End Sub
  11.  Public Sub New(gas As Double)
  12.   Me._speed = 0
  13.   Me._gas = gas
  14.  End Sub
  15.  'メソッド==========
  16.  '加速させるメソッド
  17.  Public Sub SpeedUp(sp As Integer)
  18.   'ガソリンを減らす
  19.   Me._gas -= sp / 10.0
  20.   If Me._gas < 0 Then 'ガソリンがマイナスになる場合
  21.    'ガソリンを0に補正し、スピードを増やさない
  22.    Me._gas = 0
  23.   Else
  24.    'スピードを増やす
  25.    Me._speed += sp
  26.   End If
  27.  End Sub
  28.  '減速させるメソッド
  29.  Public Sub SpeedDown(sp As Integer)
  30.   'スピードを減らす
  31.   Me._speed -= sp
  32.   If Me._speed < 0 Then     'スピードがマイナスになる場合
  33.    'スピードを0に補正する
  34.    Me._speed = 0
  35.   End If
  36.  End Sub
  37.  '初期化を行うメソッド
  38.  'Public Sub Init(gas As Double)
  39.  ' Me._speed = 0
  40.  ' Me._gas = gas
  41.  'End Sub
  42.  'スピードを取得する
  43.  Public Function GetSpeed() As Integer
  44.   Return Me._speed
  45.  End Function
  46. (そのほかの記述…)

○ クラス図

○ 解説

 10~12行目でコンストラクタを定義しています。このコンストラクタは引数を受け取らず、呼び出されたらもう一つの引数を受け取るコンストラクタにガソリン量を表す「20」を渡して呼び出しています。

 14~17行目では引数を受け付けるコンストラクタを定義しています。スピード情報に「0」をセットし、ガソリン量を引数で受け取ったデータでセットします。

 44~47行目では、コンストラクタを定義することにより初期化を行うメソッドが不要になったので、コメントアウト(削除)しています。

○ プログラム

 コンストラクタが用意されたので、インスタンスを生成する記述も変更しましょう。

Module1.vb

  1. Sub Main()
  2.  'インスタンスを生成する
  3.  Dim obj As New Car(40)
  4.  'フィールド変数を初期化する
  5.  'obj._speed = 0
  6.  'obj._gas = 20.0
  7.  'obj.Init(20)
  8.  '現在の状態を表示する
  9.  ShowData(obj)
  10.  While True
  11.   '操作を入力
  12.   Console.Write("1)加速 2)減速 3)給油 9)終了:")
  13.   Dim inputdata As String = Console.ReadLine()
  14.   '操作によって分岐する
  15.   Select Case inputdata
  16.    Case "1"
  17.     '加速する
  18.     obj.SpeedUp(5)
  19.     ShowData(obj)
  20.    Case "2"
  21.     '減速する
  22.     obj.SpeedDown(5)
  23.     ShowData(obj)
  24.    Case "3"
  25.     '給油する
  26.     obj.SetGas(35)
  27.     ShowData(obj)
  28.    Case "9"
  29.     'プログラムを終了する
  30.     Return
  31.   End Select
  32.  End While
  33. End Sub

○ 解説

 18行目で、フィールドを初期化するメソッドの呼び出しは廃止されたため、コメントアウトして実行させないようにしました。その代わりに用意されたコンストラクタで初期化をするために13行目では、インスタンス生成時の引数にガソリン量のデータを渡しています。

 前節まではコンストラクタを定義していませんでした。しかし、インスタンス生成時に「New Car()」としていました。コンストラクタを定義していない場合は、引数なし・処理なしのコンストラクタが仮定されて、インスタンスが生成されます。なお、引数を持たないコンストラクタのことを「デフォルトコンストラクタ」と呼びます。

デフォルトコンストラクタのイメージ
デフォルトコンストラクタのイメージ

 今回のように引数を持つコンストラクタが1つでも定義されている場合は、デフォルトコンストラクタは仮定されません。デフォルトコンストラクタを使用したい場合は引数を持たないコンストラクタを明示的に定義しなくてはなりません。

デフォルトコンストラクタは仮定されない
デフォルトコンストラクタは仮定されない

 なお、コンストラクタもオーバーロードさせることができます。コンストラクタ内で同じクラスにある別のコンストラクタを呼ぶ場合は「Car.vb」の11行目にあるように、コンストラクタの定義の最初の行に「 Me.New()」のように記述をします。

前へ   次へ