コンストラクタ

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

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

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

○ プロジェクト

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

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

サンプルダウンロード

○ 作成の準備

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

○ プログラム

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

Car.cs

  1. class Car
  2. {
  3.  //フィールド==========
  4.  private int speed; //スピード
  5.  private double gas; //ガソリン情報
  6.  //コンストラクター==========
  7.  public Car() : this(20)
  8.  {
  9.  }
  10.  public Car(double gas)
  11.  {
  12.   this.speed = 0;
  13.   this.gas = gas;
  14.  }
  15.  //メソッド==========
  16.  //加速させるメソッド
  17.  public void SpeedUp(int sp)
  18.  {
  19.   //ガソリンを減らす
  20.   this.gas -= sp / 10.0;
  21.   if(this.gas < 0) //ガソリンがマイナスになる場合
  22.   {
  23.    //ガソリンを0に補正し、スピードを増やさない
  24.    this.gas = 0;
  25.   }
  26.   else
  27.   {
  28.    //スピードを増やす
  29.    this.speed += sp;
  30.   }
  31.  }
  32.  //減速させるメソッド
  33.  public void SpeedDown(int sp)
  34.  {
  35.   //スピードを減らす
  36.   this.speed -= sp;
  37.   if(this.speed < 0) //スピードがマイナスになる場合
  38.   {
  39.    //スピードを0に補正する
  40.    this.speed = 0;
  41.   }
  42.  }
  43.  ////初期化を行うメソッド
  44.  //public void Init(double gas)
  45.  //{
  46.  // this.speed = 0;
  47.  // sthis.gas = gas;
  48.  //}
  49.  //スピードを取得する
  50.  public int GetSpeed()
  51.  {
  52.   return this.speed;
  53.  }
  54.  //ガソリン量を取得する
  55.  public double GetGas()
  56.  {
  57.   return this.gas;
  58.  }
  59.  //ガソリンを給油するメソッド
  60.  public void SetGas()
  61.  {
  62.   //オーバーロードしているメソッドを呼び出す
  63.   this.SetGas(20);
  64.  }
  65.  public void SetGas(double gas)
  66.  {
  67.   //止まっている場合は指定したガソリン量を給油
  68.   if (this.speed == 0)
  69.   {
  70.    this.gas += gas;
  71.   }
  72.  }
  73. }

○ クラス図

○ 解説

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

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

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

○ プログラム

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

Program.cs

  1. static void Main(string[] args)
  2. {
  3.  //インスタンスを生成する
  4.  Car car = new Car(40);
  5.  ////フィールド変数を初期化する
  6.  //car.Init(20);
  7.  //現在の状態を表示する
  8.  ShowData(car);
  9.  while (true)
  10.  {
  11.   //操作を入力
  12.   Console.Write("1)加速 2)減速 3)給油 9)終了:");
  13.   string inputdata = Console.ReadLine();
  14.   //操作によって分岐する
  15.   switch (inputdata)
  16.   {
  17.    case "1":
  18.     //加速する
  19.     car.SpeedUp(5);
  20.     ShowData(car);
  21.     break;
  22.    case "2":
  23.     //減速する
  24.     car.SpeedDown(5);
  25.     ShowData(car);
  26.     break;
  27.    case "3":
  28.     //給油する
  29.     car.SetGas(35);
  30.     ShowData(car);
  31.     break;
  32.    case "9":
  33.     //プログラムを終了する
  34.     return;
  35.   }
  36.  }
  37. }

○ 解説

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

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

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

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

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

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

前へ   次へ