コンテンツへスキップ

【C# の基本】レッスン7:② クラスとカプセル化


概要

前回は、オブジェクト指向の考え方について学びました。少しおさらいしてみましょう。

オブジェクト指向の一番の特徴はカプセル化です。オブジェクト(下図の場合、プレイヤーや宝石)は、自分に関係する「データ」と「処理」をもちます。そして、データの内容を読み込んだり書き込んだりできるのは、基本的には自分の「処理」からだけに設計(プログラミング)します。こうすることで、データが色んなプログラムから書き込まれることを防ぐことができます。

lesson7-1-2

では、実際のプログラムを例にして、オブジェクト指向について考えていきましょう。下記は、プレイヤーのスクリプトファイル「PlayerController.cs」を図で示したものです。データ部分(maxSpeed、spriteRenderer)と処理部分(Awake メソッド、Update メソッド、JumpState)がクラス(PlayerController)によってカプセル化されています。

lesson7-2-1

カプセル化で重要なキーワードがあります。それは「可視性」です。ゲームなどのプログラムでは、オブジェクトを複数扱うことが多いと思います。このとき、データや処理を自分のクラスの中からしかアクセスできないとしたら、オブジェクト間の連携が取れません。当たり判定などが実現できないため、ゲームとして成立しないでしょう。そこでデータや処理(メソッドといいます)には「可視性」をつけます。

「可視性」は、「public」や「private」といったアクセス修飾子をつけることで設定します。「public」は、日本語で「公開」という意味です。「public」がついたデータやメソッドは、他のクラスからアクセス可能という意味になります。一方の「private」は「非公開」という意味です。「private」がつくと、他のクラスからアクセスすることはできなくなり、自分のクラス内からのみアクセス可能となります。

アクセス修飾子がついていないデータやメソッドがあると思います。この場合は、プログラミング言語によって可視性は異なります。C# の場合は、「private」となります。アクセス修飾子の省略はバグにつながりやすいので、すべてのデータやメソッドにアクセス修飾子をつけることを推奨します。

STEP1:C# プログラム(ファイル)を追加する

こちらの記事を参考にして、コンソールアプリ(プロジェクト名:Lesson7)と C# プログラム(ファイル名:Lesson7_2)を追加します。

STEP2:プログラムを記述する

Lesson7_2.cs のプログラムを下記のように変更します。

namespace Lesson7
{
    public static class Lesson7_2
    {
        /// <summary>
        /// public なデータ
        /// </summary>
        public static int publicVal = 0;
     
        /// <summary>
        /// private なデータ
        /// </summary>
        private static int privateVal = 0;

        /// <summary>
        /// public メソッド
        /// </summary>
        public static void publicMethod()
        {
            Console.WriteLine("★publicVal の値:{0}", publicVal);

            privateMethod();
        }

        /// <summary>
        /// private メソッド
        /// </summary>
        private static void privateMethod()
        {
            Console.WriteLine(" privateVal の値:{0}", privateVal);
        }
    }
}

STEP3:可視性を確認する

「Program.cs」ファイルを以下のように変更し、実行してみてください。

namespace Lesson7
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Lesson7_2.publicVal = 10;
            Lesson7_2.privateVal = 10;

            Lesson7_2.publicMethod();
            Lesson7_2.privateMethod();
        }
    }
}

「Program」クラスから、「Lesson7_2」クラスのデータやメソッドにアクセスしています。全てのデータやメソッドにアクセスできますか。アクセスできないとしたら、アクセス修飾子はどのようになっていますか。確認してみましょう。

課題①:「PlayerController.cs」の変数「maxSpeed」の可視性を「private」に変更してみよう

次のようにアクセス修飾子を変更します。

/// <summary>
/// Max horizontal speed of the player.
/// </summary>
private float maxSpeed = 7;

変更したら、Unity エディタを開きます。すると、下図のようにエディタの下にエラーメッセージが表示されると思います。日本語に訳すと「PlatformerSpeedPad クラスから、PlayerController クラスの maxSpeed にはアクセスできませんよ」という意味になります。

lesson7-2-2

課題②:Unity のインスペクターから private な変数にアクセスする

変数を「private」で宣言することで、他のクラスからの値の変更を防ぐことができます。このように設計すると、オブジェクト指向の恩恵(保守性の向上)を受けることができます。ただし、Unity のエディタから変数の値をセットできると便利だと思いませんか。

private で変数を宣言しつつも、Unity エディタからその変数にアクセスできるようにする仕組みがあります。それは「SerializeField」を使うことです。下記のようになります。

/// <summary>
/// Max horizontal speed of the player.
/// </summary>
[SerializeField]
private float maxSpeed = 7;

次に進む

次は、インスタンスについて学びます。