基礎から学ぶC#入門 90日コース | クラス・インスタンス・設計 - Day 33:コンストラクタ

Web APP 90日で身につけるC#
スポンサーリンク
スポンサーリンク

Day 33 のゴールと全体像

Day 33 のテーマは コンストラクタ です。 いよいよ「オブジェクトが生まれる瞬間」を、ちゃんとコントロールできるようになっていきます。

学ぶことは次の 4 つです。

  • コンストラクタ
  • 初期化
  • 引数付きコンストラクタ
  • オーバーロード

ざっくり言うと、

new したときに、オブジェクトをどう準備させるか」

を学ぶ回だと思って読んでいただけると、イメージしやすいと思います。

コンストラクタとは何か

「生まれた瞬間に呼ばれる特別なメソッド」

コンストラクタは、

オブジェクトが new された瞬間に、自動で呼ばれる特別なメソッド

です。

特徴を整理すると、

  • クラス名と同じ名前を持つ
  • 戻り値の型を書かない(void も書かない)
  • new クラス名(...) としたときに自動で実行される

まずは、シンプルなコンストラクタの例を見てみましょう。

class Person
{
    public string Name;
    public int Age;

    // コンストラクタ(引数なし)
    public Person()
    {
        Console.WriteLine("Person のインスタンスが生成されました。");
        Name = "名無し"; // デフォルトの名前
        Age = 0;          // デフォルトの年齢
    }

    public void Introduce()
    {
        Console.WriteLine($"こんにちは、{Name} です。年齢は {Age} 歳です。");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // ここでコンストラクタが自動的に呼ばれます
        Person p = new Person();

        p.Introduce();

        Console.ReadLine();
    }
}
C#

このコードを実行すると、

  1. new Person() のタイミングで Person() コンストラクタが呼ばれる
  2. コンストラクタの中で NameAge が初期化される
  3. そのあとで Introduce() が呼ばれる

という流れになります。

重要ポイント:

  • コンストラクタは「オブジェクトの初期設定」をする場所です。
  • new した瞬間に必ず呼ばれるので、「必ずやっておきたい処理」を書くのに向いています。

初期化をコンストラクタにまとめる意味

「作ったあとに設定する」より「作るときに設定する」

コンストラクタがない場合、オブジェクトの初期化はこんな感じになります。

Person p = new Person();
p.Name = "太郎";
p.Age = 20;
C#

もちろんこれでも動きますが、

  • 名前を設定し忘れる
  • 年齢を設定し忘れる

といった「初期化漏れ」が起きやすくなります。

そこで、

「作るときに、必要な情報を必ず渡させる」

というスタイルにすると、ミスが減ります。 これが 引数付きコンストラクタ です。

引数付きコンストラクタ

「作るときに必要な情報を渡す」スタイル

引数付きコンストラクタは、

new するときに、初期化に必要な値を渡せるコンストラクタ」

です。

先ほどの Person を、引数付きコンストラクタで書き直してみます。

class Person
{
    public string Name;
    public int Age;

    // 引数付きコンストラクタ
    public Person(string name, int age)
    {
        Console.WriteLine("Person のインスタンスが生成されました。(引数付き)");
        Name = name;
        Age = age;
    }

    public void Introduce()
    {
        Console.WriteLine($"こんにちは、{Name} です。年齢は {Age} 歳です。");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // ここで name と age を渡しながらインスタンスを生成します
        Person p = new Person("太郎", 20);

        p.Introduce();

        Console.ReadLine();
    }
}
C#

この形だと、

  • Person を作るときに、必ず nameage を渡さないといけない
  • 「名前が未設定のまま」「年齢が未設定のまま」という状態を防げる

というメリットがあります。

重要ポイント:

  • 引数付きコンストラクタは「必須情報を強制する」ための仕組みとして、とてもよく使われます。
  • クラスを設計するとき、「このクラスは何がないと成立しないか?」を考えると、引数付きコンストラクタの形が見えてきます。

コンストラクタのオーバーロード

「状況に応じて、いくつかの作り方を用意する」

コンストラクタは、メソッドと同じように オーバーロード できます。 オーバーロードとは、

「同じ名前で、引数のパターンが違うメソッドを複数用意すること」

でしたね。

コンストラクタの場合も同じで、

  • 引数なしのコンストラクタ
  • 引数付きのコンストラクタ

などを、同じクラスの中に共存させることができます。

Person クラスのコンストラクタオーバーロード例

class Person
{
    public string Name;
    public int Age;

    // 1. 引数なしコンストラクタ
    public Person()
    {
        Console.WriteLine("引数なしコンストラクタが呼ばれました。");
        Name = "名無し";
        Age = 0;
    }

    // 2. 引数付きコンストラクタ
    public Person(string name, int age)
    {
        Console.WriteLine("引数付きコンストラクタが呼ばれました。");
        Name = name;
        Age = age;
    }

    public void Introduce()
    {
        Console.WriteLine($"こんにちは、{Name} です。年齢は {Age} 歳です。");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 引数なしコンストラクタを使う
        Person p1 = new Person();
        p1.Introduce();

        // 引数付きコンストラクタを使う
        Person p2 = new Person("花子", 25);
        p2.Introduce();

        Console.ReadLine();
    }
}
C#

このように、

  • 「とりあえずデフォルト値で作る」
  • 「ちゃんと値を指定して作る」

という 2 パターンを用意しておくことができます。

重要ポイント:

  • コンストラクタのオーバーロードは、「使う側の自由度」を上げるためのテクニックです。
  • ただし、パターンが増えすぎると分かりにくくなるので、「本当に必要な作り方だけ」に絞るのがコツです。

コンストラクタ+プロパティの組み合わせ

Day 32 の内容とつなげてみる

Day 32 で学んだ「プロパティ」と、今回の「コンストラクタ」はとても相性が良いです。

例えば、Product クラスをコンストラクタ+プロパティで設計すると、こんな感じになります。

using System;

class Product
{
    // 価格はフィールド+プロパティで管理
    private int price;

    public int Price
    {
        get { return price; }
        set
        {
            if (value < 0)
            {
                price = 0;
            }
            else
            {
                price = value;
            }
        }
    }

    // 名前は自動実装プロパティ
    public string Name { get; set; }

    // 引数付きコンストラクタ
    public Product(string name, int price)
    {
        Name = name;
        Price = price; // set 経由でチェックされます
    }

    // 引数なしコンストラクタ(オーバーロード)
    public Product()
    {
        Name = "不明";
        Price = 0;
    }

    public void PrintInfo()
    {
        Console.WriteLine($"商品名: {Name}, 価格(税抜): {Price}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 引数付きコンストラクタで作成
        Product p1 = new Product("ノート", 100);
        p1.PrintInfo();

        // 引数なしコンストラクタで作成
        Product p2 = new Product();
        p2.PrintInfo();

        Console.ReadLine();
    }
}
C#

ここでは、

  • コンストラクタで「初期値」を決める
  • プロパティで「値のチェック」を行う

という役割分担になっています。

重要ポイント:

  • コンストラクタは「最初の状態を決める場所」
  • プロパティは「その後の変更を管理する場所」

と考えると、設計がすっきりします。

Day 33 用の練習テンプレート

最後に、コンストラクタの練習に使えるテンプレートを紹介します。 自分の好きなテーマに置き換えて遊んでみてください。

ユーザークラスのテンプレート

using System;

class User
{
    // 自動実装プロパティ
    public string UserName { get; set; }
    public string Email { get; set; }

    // 引数なしコンストラクタ
    public User()
    {
        UserName = "guest";
        Email = "guest@example.com";
        Console.WriteLine("ゲストユーザーが生成されました。");
    }

    // 引数付きコンストラクタ
    public User(string userName, string email)
    {
        UserName = userName;
        Email = email;
        Console.WriteLine("ユーザーが生成されました。");
    }

    public void PrintInfo()
    {
        Console.WriteLine($"UserName: {UserName}, Email: {Email}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // ゲストユーザー
        User guest = new User();
        guest.PrintInfo();

        // 通常ユーザー
        User normal = new User("mono_user", "mono@example.com");
        normal.PrintInfo();

        Console.ReadLine();
    }
}
C#

このテンプレートをベースにして、

  • Student クラスで「名前+点数」をコンストラクタで受け取る
  • Book クラスで「タイトル+著者+ページ数」を初期化する
  • Car クラスで「メーカー+モデル+年式」を設定する

など、いろいろな「コンストラクタ付きクラス」を作ってみると、 コンストラクタの使い方が自然と身についていきます。

Day 33 のまとめ

Day 33 では、

  • コンストラクタ = オブジェクト生成時に自動で呼ばれる特別なメソッド
  • 初期化 = コンストラクタで「最初の状態」を決めること
  • 引数付きコンストラクタ = 必須情報を渡させるための仕組み
  • オーバーロード = 複数の作り方を用意して、使う側の自由度を上げる

という流れで、 「オブジェクトが生まれる瞬間を設計する」という感覚を育てました。

この先、

  • クラス同士が関係し合う設計
  • より複雑なオブジェクトのライフサイクル管理

に進んでいくとき、 今日学んだコンストラクタは、必ずと言っていいほど登場します。

ぜひ、

  • 自分でクラスを 1 つ考えて、引数なし/引数付きコンストラクタを両方作ってみる
  • 「このクラスは何がないと成立しないか?」を考えて、必須情報をコンストラクタの引数にしてみる
  • プロパティと組み合わせて、「初期化」と「その後の変更」をきれいに分けてみる

といった練習を通して、 コンストラクタを「ただの文法」ではなく、 「オブジェクトの生まれ方をデザインする道具」として、しっかり自分のものにしていってください。

タイトルとURLをコピーしました