C#のコンストラクターとは?アクセス修飾子 public と private の違いも確認する
C#でクラスからインスタンスを作成するとき、最初に実行される特別なメソッドがコンストラクターです。
例えば、次のコードを見てみましょう。
Student student = new Student();
このコードでは、Student クラスのインスタンスを作成しています。
このとき、
new Student()
が実行されると、Student クラスに定義されているコンストラクターが呼び出されます。
コンストラクターの基本形

次のように Student クラスを作成します。
class Student
{
public Student()
{
Console.WriteLine("コンストラクターが実行されました");
}
}
コンストラクターには、通常のメソッドとは異なる特徴があります。
- クラス名と同じ名前にする
- 戻り値の型を書かない
newでインスタンスを作成すると自動的に呼び出される
通常のメソッドでは、
void Show()
{
}
のように void などの戻り値の型を書きます。
しかしコンストラクターでは、
public Student()
{
}
のように、戻り値の型を書きません。
new Student() を実行するとどうなるか
次のコードを実行します。
Student student = new Student();
処理の流れは、概念的には次のようになります。
new Student()
↓
Studentクラスのインスタンスを作成
↓
Student() コンストラクターを実行
↓
変数 student に参照を代入
そのため、次のコンストラクターが定義されていれば、
public Student()
{
Console.WriteLine("コンストラクターが実行されました");
}
実行結果は次のようになります。
コンストラクターが実行されました

つまり、コンストラクターは自分で
student.Student();
などと呼び出すものではありません。
new したときに自動的に実行されるのが重要なポイントです。
コンストラクターを private にするとどうなるか
ここで、コンストラクターを次のように変更してみます。
class Student
{
private Student()
{
Console.WriteLine("コンストラクターが実行されました");
}
}
そして、先ほどと同じように、
Student student = new Student();
と書くと、Visual Studioではエラーになります。
代表的なエラーは次のものです。
CS0122:
'Student.Student()' はアクセスできない保護レベルになっています

なぜでしょうか。
private はクラスの外からアクセスできない
private は、
そのクラスの内部からだけアクセスできる
という意味です。
今回のコードでは、
private Student()
となっているため、Student クラスの外側にある Program クラスからは呼び出せません。
構造を簡略化すると、次のようになります。
Programクラス
│
│ new Student()
▼
Studentクラス
private Student()
↑
└─ 外部からはアクセス不可
そのため、
Student student = new Student();
がコンパイルエラーになります。
public にすると外部から生成できる
コンストラクターを、
public Student()
とすると、クラスの外から呼び出せるようになります。
class Student
{
public Student()
{
Console.WriteLine("コンストラクターが実行されました");
}
}
すると、
Student student = new Student();
を正常に実行できます。
この違いは非常に重要です。
| コンストラクター | new Student() |
|---|---|
public Student() | クラス外から実行できる |
private Student() | クラス外から実行できない |
private なコンストラクターは間違いではない
ここで注意したいのは、
private Student()
自体が間違ったコードというわけではないことです。
意図的に、
外部から自由にインスタンスを作らせたくない
場合に private コンストラクターを使うことがあります。
例えば、次のようなコードです。
class Student
{
private Student()
{
}
public static Student Create()
{
return new Student();
}
}
この場合、クラス外から直接、
Student student = new Student();
とは書けません。
代わりに、
Student student = Student.Create();
とします。
Create() は Student クラス自身の内部にあるため、
new Student()
を実行できます。
このように、インスタンスを作る方法をクラス側で制御したい場合にも private コンストラクターが利用されます。
引数付きコンストラクター
コンストラクターには引数を持たせることもできます。
例えば、学生の名前をインスタンス生成時に設定したい場合です。
class Student
{
public string Name;
public Student(string name)
{
Name = name;
}
}
呼び出す側では、
Student student = new Student("田中");
とします。
このとき、
"田中"
がコンストラクターの、
string name
に渡されます。
その結果、
Name = name;
によって、インスタンスの初期値を設定できます。
コンストラクターの大きな役割の一つは、インスタンスを作った直後の初期状態を整えることです。
コンストラクターは複数作れる
C#では、引数の組み合わせが異なれば、同じ名前のコンストラクターを複数定義できます。
class Student
{
public string Name;
public int Score;
public Student()
{
Name = "未設定";
Score = 0;
}
public Student(string name)
{
Name = name;
Score = 0;
}
public Student(string name, int score)
{
Name = name;
Score = score;
}
}
すると、次のいずれも利用できます。
Student student1 = new Student();
Student student2 = new Student("田中");
Student student3 = new Student("田中", 80);
このように、同じ名前で引数の違うメソッドやコンストラクターを用意することをオーバーロードと呼びます。
Visual Studioでも、コンストラクターに複数の候補がある場合、
+ 1 オーバーロード
のように表示されることがあります。
コンストラクターを書かなかった場合
実は、次のようにコンストラクターを書かなくても、
class Student
{
}
通常は、
Student student = new Student();
と書くことができます。
これは、コンストラクターを1つも定義していない場合、C#コンパイラが引数なしのコンストラクターを用意してくれるためです。
イメージとしては、
class Student
{
public Student()
{
}
}
が存在するようなものです。
ただし、自分でコンストラクターを1つでも定義すると、この自動的な引数なしコンストラクターは作られません。
例えば、
class Student
{
public Student(string name)
{
}
}
とすると、
Student student = new Student();
はエラーになります。
利用できるのは、
Student student = new Student("田中");
です。
まとめ
コンストラクターは、クラスからインスタンスを作成するときに自動的に実行される特別なメソッドです。
Student student = new Student();
と書いたとき、
Student()
というコンストラクターが呼び出されます。
基本形は次の通りです。
public Student()
{
}
特に重要なのがアクセス修飾子です。
public Student()
ならクラスの外から、
new Student()
を実行できます。
一方、
private Student()
にすると、クラスの外から直接インスタンスを生成できません。
今回の例は、コンストラクターの仕組みだけでなく、public と private が実際のコードにどのような影響を与えるかを確認するのにも非常に分かりやすい例です。










ディスカッション
コメント一覧
まだ、コメントがありません