【C#】クラス構成要素を整理しよう

とうとうクラスに関する内容も最後まできました。この記事では新しいことは行わずに、これまでのクラスに関連する話題を一気に総まとめする内容に入りたいと思います。

C#においてクラスの概念は超重要なのですが、これが意外と定着しない考え方なので何度も復習して身体に染み込ませていく必要があります。その復習材料としても、この記事を活用してもらえればうれしく思います。

サンプルコード

それでは新規のコンソールアプリケーションを作成して、以下のソースを記述してみてください。

using System;

namespace App01
{
    class Program
    {
        static void Main(string[] args)
        {
            //Taroさんをインスタンス化する
            Person Taro = new Person();
            Taro.Name = "Taro";
            Taro.WriteName();

            //Hanakoさんをインスタンス化する
            Person Hanako = new Person();
            Hanako.WriteName();
            //再設定する
            Hanako.Name = "Hanako";
            Hanako.WriteName();

            Console.ReadLine();
        }

        //人間クラス
        public class Person
        {
            //コンストラクター
            public Person()
            {
                _name = "";
            }

            //プロパティ
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }
            //フィールド
            private string _name;

            //メソッド
            public void WriteName()
            {
                if(_name == "")
                {
                    Console.WriteLine("名前を設定してください。");
                }
                else
                {
                    Console.WriteLine("I'm " + _name);
                }
            }
        }
    }
}

記述が完了したら、是非とも動かして動作を確認しておきましょう。どのように動くのかを頭の中でシュミレートしてみてください。コードについては、これから解説していきます。

クラス

まずはクラスの定義から確認していきます。当サンプルにてクラスを定義しているのは以下の箇所になります。

//人間クラス
public class Person
{
    //この中身は省略
}

「public class (クラス名)」でクラスを定義することができます。クラスは「オブジェクトの設計書」のような役割をしており、内部の構成要素によってクラスのあり方を定義できます。

クラスをインスタンス化する(実体を生成する)には「new」キーワードを使用する必要がありました。「(クラス名)(インスタンス変数名) = new (クラス名)();」として記述します。

//Taroさんをインスタンス化する
Person Taro = new Person();

また、同一クラスから別々にインスタンス化されたオブジェクトは、同じ設計図から作成されていますが、存在としては別物として扱われます。これがサンプルにおける「Taro」と「Hanako」に対応します。

コンストラクター

コンストラクターはクラスをインスタンス化したタイミングで起動する特殊なメソッドであり、「オブジェクトを正しく初期化する」ためのメソッドです。Personクラスではコンストラクター内部で「_name」を初期化するようにしています。

//コンストラクター
public Person()
{
    _name = "";
}

コンストラクターは戻り値を持たない特殊なメソッドですので、voidや戻り値の型をアクセス修飾子の後に記述しないことは覚えておきましょう。

プロパティ

プロパティはクラス内部・外部に対する変数のアクセス機能を提供する役割を担っています。外側からのアクセスに対して、特定のデータを返却し、また外部からの設定に対して、対応する変数に値を設定する役割を持っています。

//プロパティ
public string Name
{
    get { return _name; }
    set { _name = value; }
}

プロパティでは「get / set」を使ってコーディングします。「クラスの外側からgetする」「クラスの外側からsetする」と覚えておくと、getとsetがどちらだったか忘れないと思います。

プロパティを記述する際はフィールドも併せて定義することが多いのが特徴です。getやsetの波括弧内には処理を記述できるので、アクセスに対して処理が必要な場合は適宜、必要な処理を記述することが可能です。

フィールド(メンバ変数)

フィールドはクラス内に持つ「データ」を格納する変数に対して使われます。フィールドだけでなく、メンバ変数とも呼ばれることがあります。プロパティはクラス内外のアクセスに対する機能を提供しますが、フィールドにはそういった機能はなく、単純な変数の宣言が多いです。

//フィールド
private string _name;

基本的なお作法としては、publicなプロパティを定義して、それに対応するフィールドはprivateで定義することが多いです。こうすることで、特定のデータに対するアクセスのみ許容して、それ以外は外部に公開しないようにできます。

クラスなどを使用したプログラミングではpublicな変数を少なく定義し、フィールドに対するアクセスはプロパティで行うのが基本であると覚えておきましょう。

メソッド

クラスに対する「振る舞い」を定義する方法が「メソッド」であります。設計図に動作を記述することによって、そこから生成されるオブジェクトにて、その処理を実行することが可能となります。

//メソッド
public void WriteName()
{
    if(_name == "")
    {
        Console.WriteLine("名前を設定してください。");
    }
    else
    {
        Console.WriteLine("I'm " + _name);
    }
}

クラス内に記述するメソッドはpublicやprivateなどのアクセス修飾子を設定することができ、publicで定義するとクラスの外側からも処理の実行を行うことができます。それに対して、privateではクラス内部でしか処理の実行を行うことができません。

クラスを使って理解しやすいコードを

クラスを構成する要素について、サンプルコードを使用しながら解説してきました。クラスを使用するメリットは「オブジェクト」単位で処理を記述できることにあります。

クラスという「オブジェクトの設計図」を作成することにより、後は「使うときにインスタンス化して使用する」だけでよくなります。機能を個別に作っておき、使うときだけ実体化して使うという考え方は、現代プログラミングの「オブジェクト指向」の基礎的な考え方です。

これから先、より高度なプログラミングスキルを身に着けるためにも、クラスの定義の仕方や周辺知識などはしっかりと覚えておく必要があります。手になじむまで、これまでのサンプルコードで復習しておきましょう。