注目キーワード
  1. プログラミング
  2. C#

【C#】クラスを作成する方法(初級編:メンバ関数)

C#

はじめに

こうちゃ
こんにちは、こうちゃです。
今回は、C#のクラス作成においてメンバ関数を実装する方法を説明していきます。
今回の内容は、下記記事の続きになります。
クラスは何記事かにわけて解説予定で、前回に続き今回も初歩的な内容になります。
関連記事

はじめに こうちゃ こんにちは、こうちゃです。 今回は、C#でクラスを作成する方法 について説明していきます。 クラスは奥が深いので、何記事かにわけて解説していこうと思っています。 この記事では、一番簡単なクラスの[…]

  • クラスにおけるメンバ関数の作り方
  • クラス特有のコンストラクタ・デストラクタについて
  • クラスを作成したい方
  • オブジェクト指向に興味のある方
こうちゃ
それでは、やっていきましょう!

コンストラクタ・デストラクタ

クラスについて調べると、コンストラクタ・デストラクタ という単語をよく目にするのではないでしょうか?
どちらも関数ですが、下記のように、特別な役割があります。

コンストラクタ

  • インスタンス生成時に必ず呼ばれる
  • 名称は「クラス名」となる (クラス名が「Mob」なら、コンストラクタ名も「Mob」)
  • 戻り値は存在しない
  • 引数が異なればいくつもコンストラクタを作成できる (オーバーロード可能)
  • 明示的に定義しない場合は、デフォルトコンストラクタ が自動で呼び出される
  • メンバ変数の初期化などを行うことが多い

デストラクタ

  • インスタンス破棄時(C#の場合はガベージコレクションに回収されたタイミング) に必ず呼ばれる
  • 名称は「~クラス名」となる (クラス名が「Mob」なら、デストラクタ名は「~Mob」)
  • コンストラクタと異なり1つしか存在できない
  • 明示的に定義しない場合は、デフォルトデストラクタが自動で呼び出される
  • クラス内の後処理 (メモリ解放など) を行うことが多い
  • C#においては、デストラクタは定義しなくて良い (基本的にデフォルトで十分)

C#においては、ユーザーがデストラクタを明示的に定義することは基本的にはないので、コンストラクタを理解しておけば問題ないです。
ただ、別のプログラミング言語でクラスを扱う場合はデストラクタが必要な場合もあるので、概念は覚えておきましょう。

メンバ関数の作り方

それでは、メンバ関数を作っていきましょう。
使用するクラスは、入門編で作成したMobクラスを使用します。
今回のMobクラスのコードは以下になります。

namespace Characters
{
    class Mob
    {
        // メンバ変数
        private string name;     // 固有名
        private string status;   // 状態異常

        /// <summary>
        /// コンストラクタ1つ目(インスタンス生成時に呼ばれる)
        /// </summary>
        /// <param name="uniqueName">固有名</param>
        public Mob(string uniqueName)
        {
            // 固有名は引数で渡してもらう
            name = uniqueName;
            // 初期状態は「状態異常なし」
            status = "";
            
            Console.WriteLine($"[CTOR] Mob({name}) が生成されました。status=\"{status}\"");
        }

        /// <summary>
        /// コンストラクタ2つ目
        /// </summary>
        public Mob()
        {
            // 固有名はデフォルトを使用
            name = "デフォルトモブA";
            // 初期状態は「状態異常なし」
            status = "";

            Console.WriteLine($"[CTOR] Mob({name}) が生成されました。status=\"{status}\"");   
        }

        /// <summary>
        /// 固有名の取得
        /// </summary>
        /// <returns>固有名</returns>
        public string GetName()
        {
            return name;
        }

        /// <summary>
        /// 状態異常を付与する
        /// </summary>
        /// <param name="newStatus">付与する状態異常</param>
        public void SetStatus(string newStatus)
        {
            // 引数で渡された状態異常を設定
            status = newStatus;

            Console.WriteLine($"[METHOD] {name} に状態異常 \"{status}\" を付与しました。");
        }

        /// <summary>
        /// 状態異常を取得する
        /// </summary>
        /// <returns>現在の状態異常</returns>
        public string GetStatus()
        {
            return status;
        }

        /// <summary>
        /// 状態異常を解除する
        /// </summary>
        public void ClearStatus()
        {
            // 状態異常を初期化
            status = "";

            Console.WriteLine($"[METHOD] {name} の状態異常を解除しました。");
        }
    }
}

前回はメンバ変数のnameとstatusがあったのみでしたが、関数を6つ追加しています。(コンストラクタが2つ)

コンストラクタは引数に「uniqueName」を持ったものと、引数なしのものを作成しました。
このように、コンストラクタは引数を設定可能で、かつ複数作成できます。
また前回は、メンバ変数のnameがpublicだったため外部から直接変更できましたが、今回はprivateにし、コンストラクタでのみ設定可能にしています。

続いて、「GetName」という関数を追加しています。
メンバ変数nameがpublicからprivateに変更になっているため、外部からnameを取得するために作成された関数です。
メンバ変数は外部から直接参照できないようにprivateにし、今回のように関数を通して設定・取得するのが一般的です。

次に、「SetStatus」「GetStatus」という関数です。
こちらもname同様に、前回はpublicだった変数statusがprivateになったため必要になりました。

最後に「ClearStatus」です。
状態異常なので治ることも考えて状態異常解除という関数を作成しました。

このように、クラス内部に作成された関数がメンバ関数です。
クラス内の関数ですので、クラスが所有している変数にもアクセスが可能になっています。

メンバ関数の使い方

続いて、作成したメンバ関数を使用する方法を見ていきます。

using Characters;

namespace Main
{
    class Program
    {
        static void Main(string[] args)
        {
            // インスタンス作成(コンストラクタ呼び出し)
            Mob mobA = new Mob("モブA");
            Mob mobB = new Mob("モブB");
            Mob mobDefault = new Mob();

            // 各インスタンスに状態異常設定
            mobA.SetStatus("どく");
            mobB.SetStatus("まひ");
            mobDefault.SetStatus("やけど");

            // 各インスタンスの固有名を取得
            string nameA = mobA.GetName();
            string nameB = mobB.GetName();
            string nameDefault = mobDefault.GetName();

            // 取得した固有名を出力
            Console.WriteLine($"mobA.name = {nameA}");
            Console.WriteLine($"mobB.name = {nameB}");
            Console.WriteLine($"mobDefault.name = {nameDefault}");

            // 各インスタンスの状態異常を取得
            string statusA = mobA.GetStatus();
            string statusB = mobB.GetStatus();
            string statusDefault = mobDefault.GetStatus();

            // 取得した状態異常を出力
            Console.WriteLine($"mobA.status = \"{statusA}\"");
            Console.WriteLine($"mobB.status = \"{statusB}\"");
            Console.WriteLine($"mobDefault.status = \"{statusDefault}\"");

            // 状態異常を初期化
            mobA.ClearStatus();
            mobB.ClearStatus();
            mobDefault.ClearStatus();

            // 各インスタンスの状態異常を取得
            statusA = mobA.GetStatus();
            statusB = mobB.GetStatus();
            statusDefault = mobDefault.GetStatus();

            // 取得した状態異常を出力
            Console.WriteLine($"mobA.status = \"{statusA}\"");
            Console.WriteLine($"mobB.status = \"{statusB}\"");
            Console.WriteLine($"mobDefault.status = \"{statusDefault}\"");
        }
    }
}

上から見ていきましょう。
まず、インスタンス作成です。
ここでコンストラクタが登場します。
mobAとmobBは引数付きのコンストラクタを呼び出し、自身で好きな名前 (今回は”モブA”と”モブB”) をつけます。
mobDefaultは引数なしのコンストラクタを呼び出します。
引数なしのコンストラクタなので、mobDefaultがどんな固有名か、現時点では外からは分かりません。

続いて、各インスタンスに状態異常を付与していきます。
コードを見るとわかる通り、メンバ関数は インスタンス.メソッド という形で呼び出せます。(メンバ変数も同じでしたね)

同じように、固有名と状態異常を取得し、それぞれをコンソールに出力します。
最後に状態異常を解除し、状態異常取得、コンソール出力を行っています。

ここで今回大事なのは、メンバ関数の呼び出しは インスタンス.メソッド で行えるということです。

実行結果

それでは、上記のコードを実行してみましょう。
以下のような出力が得られると思います。

[CTOR] Mob(モブA) が生成されました。status=""
[CTOR] Mob(モブB) が生成されました。status=""
[CTOR] Mob(デフォルトモブA) が生成されました。status=""
[METHOD] モブA に状態異常 "どく" を付与しました。
[METHOD] モブB に状態異常 "まひ" を付与しました。
[METHOD] デフォルトモブA に状態異常 "やけど" を付与しました。
mobA.name = モブA
mobB.name = モブB
mobDefault.name = デフォルトモブA
mobA.status = "どく"
mobB.status = "まひ"
mobDefault.status = "やけど"
[METHOD] モブA の状態異常を解除しました。
[METHOD] モブB の状態異常を解除しました。
[METHOD] デフォルトモブA の状態異常を解除しました。
mobA.status = ""
mobB.status = ""
mobDefault.status = ""

mobA、mobB、mobDefaultのコンストラクタがそれぞれ呼ばれ、mobAとmobBには引数で指定した名前が付いていることがわかります。
また、状態異常についても付与した状態異常が設定されていることがわかります。
状態異常解除後は、メンバ変数statusが空文字になっていることも確認できました。

さいごに

今回は、クラスのメンバ関数について説明しました。

Mobというクラスに対して3つのインスタンスを作成し、それぞれのインスタンスにおいてメンバ関数を呼び出し、固有名や状態異常の設定ができることを確認しました。
クラスは変数を持っていて、その変数を制御するために関数を呼び出す。
これが基本的なクラスの使い方だと言えると思います。

前回も言いましたが、クラスは本当に奥が深いです。
前回・今回の内容は超基礎的な内容で、これから難易度がどんどん上がっていきます。
でも、クラスを扱えるのと扱えないのとでは、プログラミングの幅が大きく変わるので、少しずつでも習得できると楽しくなってくるはずです。

次回はプロパティあたりを解説しようと思っています。(変更するかも?)
今回はここまで♪

こうちゃ
それではみなさま、お疲れ様でした!
楽しいプログラミングライフを!
最新情報をチェックしよう!