[C# 入門] クラスのインスタンスについて

今回はクラスのインスタンスについてです。

クラスについての記事にインスタンスというワードが出てきましたが、少しくわしく解説します。

スポンサーリンク

インスタンスとは?

クラスについてで「クラスを使えるようにするには、newキーワードを使ってインスタンスを作成します。」と書きました。

クラスはユーザーが作る新しいデータ型です。
クラスの定義(宣言)はパソコンに「こんなデータ型があります」と教えるためのものです。
実際にクラスを使うためにはパソコンに頼んでクラスを使える状態にしてもらいます。

頼まれたパソコンはメモリー上にクラスのフィールドを格納するための場所を作ったり、
メソッドがどんな引数が必要でどういう処理をするのかという情報を作成します。
これがそのクラスのインスタンスと呼ばれるものです。

インスタンスが作られるとパソコンはここに作ったという場所情報を返してきます。
これを変数に入れるとクラスが使える状態になります。

class Sample
{
    public int X;
    public void Method() { }
}

class Program
{
    public static void Main()
    {
        Sample a = new Sample();
    }
}

こんなイメージ、

[C#]インスタンスの作成

変数aはクラスのインスタンスを差し示しています。
この状態の変数aをクラスのオブジェクトと呼んだりします。
こんなイメージ、

[C#]クラスのオブジェクト

そもそもなんでこんなことが必要か?

値型と呼ばれるintboolなどは使用するバイト数が決まっているので、変数の宣言時にメモリー上に必要な分だけ領域が確保されます。

クラスは変数やメソッドを自由に組み合わせて使われるので、どのくらいの領域(バイト数)が必要なのかわかりません。なので「こんなデータとメソッドの組み合わせです」という情報をもとに領域を確保する必要があります。
こちらは、変数にインスタンスの場所が格納されるので参照型と呼ばれます。

というわけで、
参照型に分類される型はサイズがあらかじめ決まっていないのでインスタンスを作成する必要があります。参照型はクラスの他に配列やインターフェースなどがあります。

クラスインスタンスのメンバーへのアクセス

「変数a.フィールド名」とすると、クラスインスタンスのフィールドを指し示します。

[C#]インスタンス_フィールドへのアクセス

「変数a.メソッド名」 とするとクラスインスタンスのメソッドを指し示します。

[C#]インスタンス_メソッドへのアクセス

それぞれのインスタンス

インスタンスは new を実行するごとに新しく作成されます。
クラスのインスタンスを3つ作成してみます。

class Sample
{
    public int X;
    public void Method() { }
}

class Program
{
    public static void Main()
    {
        Sample a = new Sample();
        Sample b = new Sample();
        Sample c = new Sample();
    }
}

変数a変数b変数cそれぞれ別のインスタンスを差し示しています。

[C#]別々のインスタンスを作成
スポンサーリンク

フィールドに値を設定してみる

2つ変数がそれぞれ別のインスタンスを指している場合と、
2つ変数が同じインスタンスを指している場合、違う動きをするため注意が必要です。

それぞれのインスタンスを指している場合

フィールドにint型の変数X、Yを持っているクラスを定義し、
2つのインタンスを作成し、それぞれのフィールドに値を設定してみます。

class Sample
{
    public int X;
    public int Y;
}

class Program
{
    public static void Main()
    {
        Sample a = new Sample();
        Sample b = new Sample();

        a.X = 10;
        a.Y = 20;

        b.X = 30;
        b.Y = 40;

        System.Console.WriteLine($"a.X = {a.X}, a.Y = {a.Y}");
        System.Console.WriteLine($"b.X = {b.X}, b.Y = {b.Y}");
    }
}

結果はこんな感じです。

a.X = 10, a.Y = 20
b.X = 30, b.Y = 40

11、12行目でそれぞれのインスタンスが作成され、変数a、bがそれらを差している状態になります。

[C#]インスタンスの参照先

14~18行目で、
それぞれが指しているインスタンスのフィールドにアクセスしてそれぞれ値が設定されます。

[C#]インスタンスの別々の参照先

同じインスタンスを指している場合

フィールドにint型の変数X、Yを持っているクラスを定義し、
2つの変数が同じインスタンスを指している状態でフィールドの値を設定してみます。

class Sample
{
    public int X;
    public int Y;
}

class Program
{
    public static void Main()
    {
        Sample a = new Sample();
        Sample b = a;  // 変数aの参照情報を変数bに代入

        a.X = 10;
        a.Y = 20;

        b.X = 30;
        b.Y = 40;

        System.Console.WriteLine($"a.X = {a.X}, a.Y = {a.Y}");
        System.Console.WriteLine($"b.X = {b.X}, b.Y = {b.Y}");
    }
}

結果はこんな感じです。

a.X = 30, a.Y = 40
b.X = 30, b.Y = 40

変数a、変数bのフィールドに同じ値が設定されています。
どういうことかというと、

11行目でSampleクラスのインスタンスを作成しています。
12行目で11行目で作成したインスタンスの参照情報をコピーしています。
こんな状態になります。

[C#]インスタンスの参照先(同じ場合)

14、15行目でインスタンスのフィールドXに10Yに20を設定しています。

[C#]インスタンスの参照先(同じ場合)2

17、18行目でインスタンスのフィールドXに30Yに40を設定しています。
変数bは変数aと同じインスタンスを指しているのでフィールドの値が上書きされます。

[C#]インスタンスの参照先(同じ場合)3

C# プログラミング講座に戻る

コメント

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