プログラミングと開発方法論と情報セキュリティ(主に初心者向け、言語はC#)、その他、ゲーム、思想等。

開発方法論萌え

未分類

C#応用編第4回 – コンストラクタ

投稿日:


今回はオブジェクト指向第4弾、コンストラクタを扱います。

前提

本記事は、次の記事の続編となります。

まだ読んでいない方はまずは先にこちらをお読みください。

C#応用編第1回 – クラスの前提事項

C#応用編第2回 – いよいよクラス登場!

C#応用編第3回 – 関数のクラス間移動と this 参照(this ポインタ)

IntList クラスの更なる問題点

前回、Add() 関数を IntList クラスのインスタンス関数にしたのでした。まだまだ改良の余地があるのですが、比較的すぐに終わるものから改良していきます。

前回作成したサンプルコードを見てみます。(赤字の部分に注目。)


using System;

class Program
{
  static void Main(string[] args)
  {
    IntList hoge = new IntList();
    hoge.array = new int[0];
    Console.WriteLine("好きな数だけ数値を入力してください。");
    while (true)
    {
      string str = Console.ReadLine();
      if (str == "")
        break;

      hoge.Add(int.Parse(str));
    }

    int sum = 0;
    for (int i = 0; i < hoge.length; i++)
    {
      sum += hoge.array[i];
    }

    Console.WriteLine("合計は {0} になりました。", sum);
  }
}

class IntList
{
  public int[] array;
  public int length;

  public void Add(int a)
  {
    if (length < array.Length)
    {
      // 物理的な要素数が足りている場合は新規の要素を追加するだけで良い。
      array[length] = a;
      length++;
    }
    else
    {
      // 物理的な要素数が足りない場合は配列を拡張する。

      int[] newArray;
      if (array.Length == 0)
      {
        // 配列の要素が 0 の場合は要素数が 1 の配列を作成する。
        newArray = new int[1];
      }
      else
      {
        // 既にある配列の倍の要素を持つ配列を作成する。
        newArray = new int[array.Length * 2];
      }

      // 既にある要素を複製する。
      for (int i = 0; i < array.Length; i++)
      {
        newArray[i] = array[i];
      }

      // 新規の要素を追加する。
      newArray[length] = a;
      array = newArray;
      length++;
    }
  }
}

 

hoge.array の初期化を Main() 関数で行っています。この処理を忘れると IntList クラスの Add() 関数は正常に動作しません。

クラスはプログラムとしての部品の役割を期待されますが、この点も部品として「弱い」と言えます。

そこで、hoge.array の初期化は IntList クラスで行います。

このためには、コンストラクタと言う特殊な関数を使います。

コンストラクタ

コンストラクタは new 演算子によってインスタンスが作成されるタイミングで1度だけ呼び出される特殊な関数です。

IntList クラスのコンストラクタで hoge.array を初期化すれば、Main() 関数で初期化する必要が無くなります。

クラスの中でクラスと同じ名前の関数を書けば、それがコンストラクタになります。コンストラクタに戻り値は付けません。(void と書いてもいけません。)

この場合、コンストラクタを呼び出す Main() 関数の所属するクラス(Program)とコンストラクタの所属するクラス(IntList)が異なるため、コンストラクタに public を付けて外部から呼び出せるようにします。

IntList にコンストラクタを付けて、変数 array の初期化を行うようにしたコードはこうなります。


class IntList
{
  public int[] array;
  public int length;

  public IntList()
  {
    array = new int[0];
  }

  public void Add(int a)
  {
    // 省略
  }
}

 

実はこのような単純な代入処理ならコンストラクタで実行する必要はありません。変数の宣言と同時に初期化することができます。

こういうことです。


class IntList
{
  public int[] array = new int[0];
  public int length;

  public IntList()
  { }

  public void Add(int a)
  {
    // 省略
  }
}

 

以上で、Main() 関数で、hoge.array を初期化する必要が無くなりました。

改良後の Main() 関数はこうなります。


  static void Main(string[] args)
  {
    IntList hoge = new IntList();
    Console.WriteLine("好きな数だけ数値を入力してください。");
    while (true)
    {
      string str = Console.ReadLine();
      if (str == "")
        break;

      hoge.Add(int.Parse(str));
    }

    int sum = 0;
    for (int i = 0; i < hoge.length; i++)
    {
      sum += hoge.array[i];
    }

    Console.WriteLine("合計は {0} になりました。", sum);
  }

 

hoge.array = new int[0]; が消滅しました。

今回はここまでです。

次回はカプセル化について解説します。


-未分類

Copyright© 開発方法論萌え , 2020 All Rights Reserved Powered by STINGER.