Unity & C# 学習教材

コンストラクタ

フィールドを定義しただけでは、インスタンスを生成した直後に必要な値を設定し忘れるリスクがあります。

1
2
3
Player p = new Player();
// name の設定を忘れた
p.TakeDamage(10);  // name が null のまま使われる可能性がある

コンストラクタnew が実行されたときに自動的に呼び出されるメソッドです。パラメータを設けることで「必要な値を渡さなければインスタンスを作れない」ように強制でき、初期化忘れを防ぎます。

学習目標

前提知識


1. コンストラクタの定義

コンストラクタはクラス名と同じ名前を持ち、戻り値型(void を含む)を書きません。

書式:コンストラクタの定義

1
2
3
4
アクセス修飾子 クラス名(パラメータ)
{
    初期化処理
}
比較 通常のメソッド コンストラクタ
呼び出しタイミング 任意のタイミング new のときに自動呼び出し
戻り値型 指定する(void 含む) 書かない
名前 任意 クラス名と同じ
1
2
3
4
5
6
7
8
9
10
11
12
13
class Player
{
    public string name;
    public int hp;
    public int score;

    public Player(string playerName, int initialHp)
    {
        name = playerName;
        hp = initialHp;
        score = 0;
    }
}
1
2
3
4
5
Player p1 = new Player("Alice", 100);
Player p2 = new Player("Bob", 80);

Console.WriteLine($"{p1.name}: HP={p1.hp}");
Console.WriteLine($"{p2.name}: HP={p2.hp}");
1
2
Alice: HP=100
Bob: HP=80

new Player("Alice", 100) と書くだけで namehp が確実に設定されます。コンストラクタのパラメータが必須になるため、設定忘れがコンパイルエラーとして検出されます。


2. デフォルトコンストラクタ

コンストラクタを一つも定義しない場合、コンパイラが自動的にパラメータなしの空のコンストラクタ(デフォルトコンストラクタ)を生成します。

1
2
3
4
5
6
7
8
9
10
class Enemy
{
    public string name;
    public int hp;
    // コンストラクタを定義していない → デフォルトコンストラクタが自動生成される
}

Enemy e = new Enemy();  // OK: デフォルトコンストラクタが使われる
e.name = "Slime";
e.hp = 30;

ただし、パラメータありのコンストラクタを 1 つでも定義すると、デフォルトコンストラクタは自動生成されなくなります。

1
2
3
4
5
6
7
8
9
10
11
12
class Player
{
    public string name;

    public Player(string playerName)
    {
        name = playerName;
    }
}

Player p = new Player();        // ❌ コンパイルエラー: 引数が必要
Player p = new Player("Alice"); // ✅ OK

パラメータなしでも作れるようにしたい場合は、明示的にパラメータなしコンストラクタを追加します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Player
{
    public string name;
    public int hp;

    public Player()
    {
        name = "名無し";
        hp = 100;
    }

    public Player(string playerName, int initialHp)
    {
        name = playerName;
        hp = initialHp;
    }
}
1
2
3
4
5
Player p1 = new Player();
Player p2 = new Player("Alice", 80);

Console.WriteLine($"{p1.name}: HP={p1.hp}");
Console.WriteLine($"{p2.name}: HP={p2.hp}");
1
2
名無し: HP=100
Alice: HP=80

よくあるミス

コンストラクタに戻り値型を書いてしまう

1
2
3
4
5
6
7
8
9
class Player
{
    // ❌ NG: void を書くと通常のメソッドになりコンストラクタではなくなる
    //        new Player() で自動呼び出しされない
    public void Player(string name) { }

    // ✅ OK: 戻り値型なし
    public Player(string name) { }
}

まとめ


理解度チェック

  1. 次のコードはコンパイルエラーになりますか? 理由とともに答えてください。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    class Item
    {
        public string name;
        public int price;
    
        public Item(string itemName, int itemPrice)
        {
            name = itemName;
            price = itemPrice;
        }
    }
    
    Item i = new Item();
    
  2. 次のクラスのコンストラクタを完成させてください。namedamage を引数で受け取り、フィールドに代入してください。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    class Weapon
    {
        public string name;
        public int damage;
    
        public Weapon(/* ここを埋める */)
        {
            /* ここを埋める */
        }
    }
    
  3. (応用)name(string)・hp(int)・maxHp(int)を持つ Player クラスを定義してください。コンストラクタで name と初期 HP を受け取り、maxHphp の両方を初期 HP で初期化してください。

解答を見る
  1. コンパイルエラーになる。Item(string, int) というパラメータありのコンストラクタを定義した時点でデフォルトコンストラクタが自動生成されなくなるため、new Item() は引数不足でエラーになる。

  2. 1
    2
    3
    4
    5
    
    public Weapon(string weaponName, int weaponDamage)
    {
        name = weaponName;
        damage = weaponDamage;
    }
    
  3. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    class Player
    {
        public string name;
        public int hp;
        public int maxHp;
    
        public Player(string playerName, int initialHp)
        {
            name = playerName;
            hp = initialHp;
            maxHp = initialHp;
        }
    }
    

次のステップ

アクセス修飾子 では、フィールドやメソッドへのアクセス範囲を制御してクラスを安全に設計する方法を学びます。