半人前プログラマーの技術談議

開発したもの紹介していくブログ

C# オブジェクト指向編 コンストラクタ static 配列 part2-2

引き続きオブジェクト指向について解説していきます!

 

コンストラク

前回はインスタンス変数まで解説しました.

しかし,インスタンス変数に代入する命令文を何度も書いていては非常に手間です.

プログラムも見辛くなってしまいます.

car.number = 1;
car.name = "自動車";

 

それを解消するのが,コンストラクです.

 

コンストラクは,インスタンスが生成されるときに自動的に実行される命令を記述したものです.

 

コンストラクタの宣言は次のように記述します.

クラス名 (仮引数) {
    // 命令文
}

 

例えば,このように記述します.

class Car
{
    int number;      // 番号
    string name;     // 名前

    Car (int number, string name)
    {
        this.number = number;
        this.name = name;
    }
}

 

thisは自分自身を指し示すキーワードで,クラスのインスタンス変数や,メソッドを指し示す時に使います.

 

※thisは省略する事もできますが,メソッドの仮引数などと区別する為に付けた方がいいです.特にコンストラクタでは付けましょう.また,今回のようにインスタンス変数名と仮引数名が同じ場合は省略することが出来ません.

 

コンストラクタの宣言ができたので,インスタンスを生成する時に呼び出してみましょう.

記述は次のようになります.

new クラス名(実引数);

 

前回のインスタンス生成に実引数が付いただけです.

 

例えば,このように記述します.

Car car = new Car(1, "自動車");

 

実際に使うとこのようになります.

 

ソースコード

using System;

namespace Training
{
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car(1, "自動車");        // 自動車

            Console.WriteLine("ID:" + car.number + " 名前:" + car.name);
        }
    }

    public class Car
    {
        public int number;      // 番号
        public string name;     // 名前

        public Car (int number, string name)
        {
            this.number = number;
            this.name = name;
        }
    }
}

 

実行結果

f:id:pokoshirou:20181011090708p:plain

 

 

 

クラス変数とクラスメソッド

 

クラス変数

クラスのフィールドは,インスタンスを生成した時に,インスタンス変数として使う事ができました.

クラス変数は,インスタンスを生成しなくても使用できるフィールド(変数)です.

 

クラス変数の宣言は先頭に static キーワードを付けます.

static 変数の型 変数名;

 

クラス変数を参照するときには,クラス名に「.」を付けます.

クラス名.変数名

 

例えば,このように記述します.

static int count; 
Car.count

 

※クラス変数も,自分のクラス内での参照であれば,クラス名を省略することが出来ます.こちらは省略する事が多いです.

 

実際に使うとこのようになります.

 

ソースコード

using System;

namespace Training
{
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car(1, "自動車");        // 自動車
            Console.WriteLine("ID:" + car.number + " 名前:" + car.name);
            Console.WriteLine("コンストラクタが呼び出された回数:" + Car.count);

            Car taxi = new Car(2, "タクシー");     // タクシー
            Console.WriteLine("ID:" + taxi.number + " 名前:" + taxi.name);
            Console.WriteLine("コンストラクタが呼び出された回数:" + Car.count);

            Car bus = new Car(3, "バス");          // バス
            Console.WriteLine("ID:" + bus.number + " 名前:" + bus.name);
            Console.WriteLine("コンストラクタが呼び出された回数:" + Car.count);

            Car fireEngine = new Car(4, "消防車"); // 消防車
            Console.WriteLine("ID:" + fireEngine.number + " 名前:" + fireEngine.name);
            Console.WriteLine("コンストラクタが呼び出された回数:" + Car.count);
        }
    }

    public class Car
    {
        public static int count = 0;    // クラス変数

        public int number;      // 番号
        public string name;     // 名前

        public Car (int number, string name)
        {
            this.number = number;
            this.name = name;
            Car.count++;    // コンストラクタが呼び出された回数
        }
    }
}

 

実行結果

f:id:pokoshirou:20181011094344p:plain

 

 

 

クラスメソッド

フィールドにインスタンス変数とクラス変数があるように,メソッドにもインスタンスメソッドとクラスメソッドがあります.

インスタンスメソッドインスタンスを生成した後に使用できるメソッドで,

クラスメソッドインスタンスを生成しなくても使用できるメソッドです.

 

クラスメソッドの宣言は,クラス変数と同じように先頭に static キーワードをつけます.

static 型名 メソッド名(仮引数名) {

}

 

クラスメソッドを呼び出すには,クラス変数と同じようにクラス名にドット「.」をつけます.

クラス名.メソッド名(実引数)

 

インスタンスメソッドとクラスメソッドを使い分けて,先ほど紹介したソースコードを整理してみます.

 

ソースコード

using System;

namespace Training
{
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car(1, "自動車");        // 自動車
            car.Display();
            Car.Counter();

            Car taxi = new Car(2, "タクシー");     // タクシー
            taxi.Display();
            Car.Counter();

            Car bus = new Car(3, "バス");          // バス
            bus.Display();
            Car.Counter();

            Car fireEngine = new Car(4, "消防車"); // 消防車
            fireEngine.Display();
            Car.Counter();
        }
    }

    public class Car
    {
        public static int count = 0;    // クラス変数

        public int number;      // 番号
        public string name;     // 名前

        public Car (int number, string name)
        {
            this.number = number;
            this.name = name;
            Car.count++;    // コンストラクタが呼び出された回数
        }

        public void Display()   // インスタンスメソッド
        {
            Console.WriteLine("ID:" + this.number + " 名前:" + this.name);
        }

        public static void Counter()    // クラスメソッド
        {
            Console.WriteLine("コンストラクタが呼び出された回数:" + Car.count);
        }
    }
}

 

実行結果

f:id:pokoshirou:20181011094344p:plain

 

 Mainメソッドが見やすくなりました!

 

インスタンス配列

データ型に配列があるように,クラスのインスタンスにも配列があります.

次のように記述します.

クラス名[] 変数名 = new クラス名[要素数];

 

例えば,このように記述します.

Car[] car = new Car[4];

 

この状態では,まだインスタンスは生成されていません.

配列の領域を確保しただけなので,1つずつインスタンスを生成する必要があります.

car[0] = new Car(1, "自動車");
car[1] = new Car(2, "タクシー");
car[2] = new Car(3, "バス");
car[3] = new Car(4, "消防車");

 

実際に使うとこのようになります.

using System;

namespace Training
{
    class Program
    {
        static void Main(string[] args)
        {
            Car[] car = new Car[4];      // Car型の配列を宣言する
            
            car[0] = new Car(1, "自動車");
            car[0].Display();
            Car.Counter();

            car[1] = new Car(2, "タクシー");     // タクシー
            car[1].Display();
            Car.Counter();

            car[2] = new Car(3, "バス");          // バス
            car[2].Display();
            Car.Counter();

            car[3] = new Car(4, "消防車"); // 消防車
            car[3].Display();
            Car.Counter();
        }
    }

    public class Car
    {
        public static int count = 0;    // クラス変数

        public int number;      // 番号
        public string name;     // 名前

        public Car (int number, string name)
        {
            this.number = number;
            this.name = name;
            Car.count++;    // コンストラクタが呼び出された回数
        }

        public void Display()   // インスタンスメソッド
        {
            Console.WriteLine("ID:" + this.number + " 名前:" + this.name);
        }

        public static void Counter()    // クラスメソッド
        {
            Console.WriteLine("コンストラクタが呼び出された回数:" + Car.count);
        }
    }
}

 

実行結果 

f:id:pokoshirou:20181011094344p:plain


しかし,これでは配列のメリットを活かしていません.

名前を格納するstring型の配列を作って,それを実引数として呼び出すようにしましょう.

 

ソースコード

using System;

namespace Training
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] name = { "自動車", "タクシー", "バス", "消防車" };

            Car[] car = new Car[4];      // Car型の配列を宣言する

            for (int i = 0; i < 4; i++)
            {
                car[i] = new Car(i + 1, name[i]);
                car[i].Display();
                Car.Counter();
            }
        }
    }

    public class Car
    {
        public static int count = 0;    // クラス変数

        public int number;      // 番号
        public string name;     // 名前

        public Car (int number, string name)
        {
            this.number = number;
            this.name = name;
            Car.count++;    // コンストラクタが呼び出された回数
        }

        public void Display()   // インスタンスメソッド
        {
            Console.WriteLine("ID:" + this.number + " 名前:" + this.name);
        }

        public static void Counter()    // クラスメソッド
        {
            Console.WriteLine("コンストラクタが呼び出された回数:" + Car.count);
        }
    }
}

 

実行結果

f:id:pokoshirou:20181011094344p:plain

 

大分すっきりしました!

 

 

次回はアクセス修飾子などについて解説します!