[第12回] クラスの基本的な使い方を学ぶ|Unityで学ぶC#入門
「Unityで学ぶC#入門」の連載第11回は「アクセス修飾子の使い方を学ぶ」でした。
第12回の今回はクラスの基本的な使い方を学びます。
いよいよオブジェクト指向プログラミングの肝であるクラスの考え方について学びます。
クラスはプログラミングを学ぶにあたってとても重要な考え方の一つです。
クラスとは
クラスとは、特定オブジェクトの設計図のことです。
↓クラスイメージ図
これによって、自分が使用したい機能をあらかじめクラス(設計書)として準備しておいて、いつでも使用できるようにすることができます。
クラスに関しては説明をどれだけ聞いても理解しづらい部分があります。
ここではクラスの定義方法を簡単にご紹介したあとに、複数の例を使用してクラスの使い方をできるだけ理解していただけるようにご紹介していきます。
クラスの定義
まずはクラスの定義方法からご紹介します。
クラスは以下のように定義します。
1 2 3 |
class クラス名{ クラスの中身 } |
いたってシンプルなことがわかると思います。
クラスの中身には以下のようなものを記述します。
- メンバー
- コンストラクタ
- メソッド
以上のようなことを含めて定義すると、一般的に以下のように定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class クラス名{ //メンバー private 型 メンバー1; private 型 メンバー2; //コンストラクタ public クラス名(引数){ コンストラクタの中身 } //メソッド(外部からアクセス可能) public 型 メソッド名(){ メソッドの中身 } //メソッド(外部からアクセス不可) private 型 メソッド名(){ メソッドの中身 } } |
ここからそれぞれについて説明していきます。
メンバー
メンバーはそのクラスで使用する変数のことです。
特に難しく考える必要はありません。ただの変数です。基本的にこの変数はプライベートな変数として定義されます。
理由はこれらの変数が不用意に変更・アクセスされることを防ぐためです。
アクセス制御についてはこちらをご参考ください。
プライベートな変数であるということは、これらの変数は定義されたクラス内でのみ値を変更・参照する必要があります。
そこでコンストラクタやメソッドが用いられます。
コンストラクタ
コンストラクタはこのクラスが呼び出されたときに実行される処理です。
コンストラクタも難しく考えられがちですが、特別難しいものではありません。
後ほど例を参考に詳しく解説していきます。
メソッド
メソッドは特定の処理を実行するものです。
これを利用することで、メンバーの値を参照したり、変更したりすることができます。
メソッドに関しても後ほど例をあげて詳しくご紹介していきます。
メソッドについてはこちらをご参考ください。
インスタンス生成
クラスの定義と同じように重要なことの一つがインスタンス生成です。
インスタンスとは設計したクラスの実体のことです。
つまり、設計したクラスを利用するためにはインスタンスと呼ばれる実体を生成する必要があります。
インスタンス生成は以下のように記述します。(インスタンスを生成したいクラス(Human)とそのクラスを呼び出すスクリプト(Main))
↓インスタンスを生成したいクラス
クラスの使用例
ここからクラスについて理解が進むように複数の例を使用して解説していきます。
数学の基礎的な計算を行うシステム
数学の基礎的な計算を行うシステムをクラスを使用して作成していきます。
まずはとてもシンプルな作りのシステムで基本的な使い方を確認します。
このシステムの大まかな概要は以下の通りです。
計算クラスでは簡単な四則演算を行うメソッドを作成して、メインクラスで呼び出して使用します。
プログラムは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using System.Collections; using System.Collections.Generic; using UnityEngine; //「Calc.cs」を利用するMainクラス public class Main : MonoBehaviour { //Calc型の変数を定義 Calc calc; // Start is called before the first frame update void Start() { //インスタンスを生成する calc = new Calc(); //各計算を行なう Debug.Log("Add:" + calc.Add(3, 4)); Debug.Log("Sub:" + calc.Sub(5, 4)); Debug.Log("Mul:" + calc.Mul(32, 41)); Debug.Log("Div:" + calc.Add(10, 5)); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.Collections; using System.Collections.Generic; using UnityEngine; //計算を行う「Calcクラス」 public class Calc { //整数の足し算を行うメソッド public int Add(int a,int b){ return a + b; } //整数の引き算を行うメソッド public int Sub(int a,int b){ return a - b; } //整数のかけ算を行うメソッド public int Mul(int a,int b){ return a * b; } //整数の割り算を行うメソッド public int Div(int a,int b){ return a / b; } } |
Calcクラスはとてもシンプルな構造のクラスで、2つの整数を引数として四則演算を行うメソッドを持ったクラスです。
このクラスをMainクラスの9行目のように記述することで定義することができます。
↓Main.cs 9行目
1 |
Calc calc; |
これは、Calc型の変数calcを定義するという意味です。
ここで定義したcalcに実体を持たせるためにインスタンス生成を15行目で行います。
↓Main.cs 15行目
1 |
calc = new Calc(); |
つまり、int型の変数xを定義したり、String型の変数nameを定義することと変わりなく定義することができます。
このことからわかるように、クラスというのは自分で好きなように準備できる型という認識もできるかもしれません。
個人情報を登録するシステム
次に個人情報を登録するシステムをクラスを使用して作成していきます。
具体的に以下のような処理を行うことができるシステムを作成します。
- 名前とアドレスを入力
- 登録ボタンを押して情報をシステムに登録
- プリントボタンを押してコンソールに登録された情報を出力
先ほどの計算を行うシステムに比べてかなり大きめですが、こちらの方がよりクラスの利用目的が明確です。
このシステムの大まかな概要は以下の通りです。
入力情報を管理するInputManagerクラスと登録された情報を管理するInformationListクラスをMainクラスで扱います。
また、個人情報はInformationクラスとしてあらかじめクラス定義しておきます。
では下準備から始めていきましょう。
UI作成
まずはじめに入力フォーマットを作成します。
ヒエラルキーウィンドウのCreateからUI→InputFieldを選択してください。
これによってCanvasの下にInputField、それとは別にEventSystemが作成されました。Canvasとは入力フォームやボタンのようなUIを扱うために必要なオブジェクトです。EventSystemはキーボード入力やクリック入力などの処理を扱うために必要なオブジェクトです。
ここではこの両方について詳しく解説はしませんが、どちらも外部からの入力を扱うために必要なものだと認識しておいてください。
次に作成したInputFieldを編集します。
ヒエラルキーウィンドウでInputFieldを選択して、名前を「InputName」、Positionの値をそれぞれ0に変更してください。
次にInputField内のテキストの値を編集します。
ヒエラルキーウィンドウのInputField→Placeholderを選択して、textの中身を「Enter Name…」に変更してください。
ここまで編集すると以下のような入力フォーマットが完成します。
次にアドレスを入力するためのフォーマットも作成します。
先ほど作成した入力フォーマットを複製して、名前を「InputAddress」、PositionのY座標を「-40」、初期テキストを「Enter Address…」に変更してください。
最終的に以下のようになっていれば問題ありません。
次にボタンを作成します。
ボタンは登録ボタン(Register)とコンソール出力ボタン(Print)の2つを作成します。
登録ボタンから作成します。
ヒエラルキーウィンドウのCreate→UI→Buttonを選択してください。次に名前を「Register」、Positionの値をX=0,Y=-40、Register下のTextを「Register」に変更してください。
これで登録ボタンが完成しました。
次にコンソール出力ボタンを作成します。
先ほど作成した登録ボタンを複製して、名前を「Print」、PositionをY=80、Print下のTextを「Print」に変更してください。
最終的に以下のようになっていれば問題ありません。
スクリプト作成
スクリプトを作成していきます。
Informationクラス
Informationクラスは個人情報そのものです。このInformationクラスをInformationListクラスで複数管理するイメージです。
プログラムは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Information : MonoBehaviour { //名前とアドレスを定義 string name; string address; //コンストラクタ public Information(string name,string address) { //自分のクラスのメンバーに引数の値を代入する //this.〇〇とすることで引数とメンバーを区別することができる this.name = name; this.address = address; } //メンバーの値をコンソールに出力する関数 public void PrintMember() { Debug.Log("Name is [ " + this.name + " ]"); Debug.Log("Address is [ " + this.address + " ]"); } } |
メンバーは「name」、「address」の2つです。
この2つにコンストラクタを使用して値を渡します。つまり、インスタンス生成時に値を受け取って代入することでInformationインスタンスを生成します。
また、16,17行目の「this.〇〇」とは自分自身のメンバーを指定するときに使用するもので、コンストラクタの引数と区別して扱うことができます。
InformationListクラス
InformationListクラスは先ほど作成したInformationクラスを管理するクラスです。
プログラムは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class InformationList : MonoBehaviour { //Information型の配列を定義 Information[] informations; //配列の最大値 int max; //現在配列に入っている情報の数 int number; //配列の長さを引数として与えてインスタンス生成するコンストラクタ public InformationList(int length) { //最大値を引数の値に設定 max = length; //現在の配列の中身の個数 number = 0; //長さがlengthの配列を生成 informations = new Information[length]; } //名前とアドレス情報を受け取って配列に登録する関数 public void SetInfomation(string name,string address) { //もし配列の長さを超えてしまう場合、エラーを発する if(number == max) { Debug.Log("これ以上格納できません"); } else { //配列番号numberにInformationクラスの情報を格納する informations[number] = new Information(name, address); //numberを+1する number++; } } //配列の中身をコンソールに出力する関数 public void PrintInformations() { //for文を利用して配列の中身を出力 for (int i = 0; i < number; i++) { Debug.Log("Number." + i); informations[i].PrintMember(); } } } |
コンストラクタでは格納できる情報の数を引数として渡します。処理としては、受け取った配列の上限を変数maxに格納、現在の配列の中身の個数(最初は0)を指定、最後にInformation型の配列の長さを指定してインスタンス生成しています。
また、配列に値を格納するためのメソッドと配列の中身を取り出してコンソールに出力するメソッドの2つを記述しています。
情報を受け取って配列に格納するメソッド「SetInformation」では、現在の配列の中身の個数と最大値が同じ場合、これ以上格納できないためエラーを発しています。
格納が可能なとき、Informationsの[number]番目にInformation型の値を格納します。この部分が少し難しく感じるかもしれませんが、Information型の値を新しく作成して、そのまま配列に格納しているだけですので難しく考える必要はありません。
もしよくわからない場合は配列について改めて確認してみてください。
参考記事)配列の使い方を学ぶ
配列の中身を参照してコンソールに出力するメソッド「PringInformations」のfor文の使い方についてよくわからない場合は以下記事をご参考ください。
参考記事)for文を利用したループを学ぶ
InputManagerクラス
InputManagerクラスは入力フォーマットに関する情報を管理するクラスです。
ここで少しUnityの知識が必要になりますが、とても簡単ですのでご安心ください。
プログラムは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class InputManager : MonoBehaviour { //名前・アドレス入力フォームをそれぞれ定義する InputField inputName; InputField inputAddress; //InputManagerのコンストラクタ public InputManager() { //それぞれの入力フォームを取得してInputFieldコンポーネントを取得する inputName = GameObject.Find("InputName").GetComponent<InputField>(); inputAddress = GameObject.Find("InputAddress").GetComponent<InputField>(); } //入力された名前情報を読み取って取得する関数 public string GetInputName() { //InputNameのテキストを取得する string name = inputName.text; //入力フォームのテキストを空にする inputName.text = ""; //テキストフォームの値を取得してreturnで返す return name; } //入力されたアドレス情報を読み取って取得する関数 public string GetInputAddress() { //InputNameのテキストを取得する string address = inputAddress.text; //入力フォームのテキストを空にする inputAddress.text = ""; //テキストフォームの値を取得してreturnで返す return address; } } |
8〜20行目で名前とアドレスそれぞれのInputFieldの情報を取得します。
InputFieldクラスはすでにUnityが準備してくれているクラスで、プログラムの先頭で以下のように宣言することで使用することができます。
1 |
using UnityEngine.UI; |
「using 〇〇;」とすることで、すでに準備されたクラスなどを利用することが可能になります。
また、17,18行目のように記述することで定義したinputNameとinputAddressとUnity上の入力フォーマットをリンクさせます。
1 2 |
inputName = GameObject.Find("InputName").GetComponent<InputField>(); inputAddress = GameObject.Find("InputAddress").GetComponent<InputField>(); |
「GameObject.Find(”〇〇”)」で実際のUnity上のオブジェクトを探してくれます。探してきたオブジェクトのコンポーネント、ここではInputFieldコンポーネントを「GetComponent<InputField>()」とすることで取得することができます。
ここでは詳しく触れませんが、このようにすることでInputFieldを扱える状態になりました。
メソッドに関して、それぞれのメソッドでそれぞれのInputFieldからテキストを取得してきます。またこれらのメソッドはstring型を返すメソッドです。取得してきたテキスト情報を呼び出し元に返すことができます。
返り値についてよくわからない場合は以下記事をご参考ください。
参考記事)メソッドの使い方を学ぶ
Mainクラス
Mainクラスは今まで記述してきたクラスを扱うコントローラー的なクラスです。
構造はいたってシンプルで、InputManagerクラスとInformationListクラスをそれぞれ作成して、RegisterボタンとPrintボタンが押されたときのメソッドを記述しているだけです。
プログラムは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using System.Collections; using System.Collections.Generic; using UnityEngine; //「Calc.cs」を利用するMainクラス public class Main : MonoBehaviour { //InputManager型の変数を定義 InputManager inputManager; //InformationList型の変数を定義 InformationList informationList; // Start is called before the first frame update void Start() { //InputManagerのインスタンスを生成する inputManager = new InputManager(); //InformationListのインスタンスを生成する informationList = new InformationList(5); } //RegisterButtonが押されたときの処理 public void Register() { //InformationListに情報を格納する informationList.SetInfomation(inputManager.GetInputName(),inputManager.GetInputAddress()); } //PrintButtonが押されたときの処理 public void Print() { informationList.PrintInformations(); } } |
Unityではボタンが押されたときに特定メソッドを呼び出すことが可能なため、わざわざここでメソッド化しています。
このMain.csを適当なオブジェクトに取り付けて使用します。
ここでは空のオブジェクトを作成してMain.csをアタッチします。アタッチしたら、それぞれのボタンが押されたときの処理を設定します。以下のGIFを参考にボタンに処理を設定してみてください。
これで実際に実行できる状態になりました。実行して確認してみましょう。
登録した情報が保存されてコンソールに出力される状態になりました。
それぞれのクラスの詳細説明は省きましたが、今までの「Unityで学ぶC#入門」を進めていただければ理解できるレベルですのでぜひチャレンジしてみてください。
まとめ
いかがでしたでしょうか。
今回はクラスの基本的な使い方についてご紹介してきました。
簡易的な例と具体的な例の2つを中心に解説してきましたが、クラスは実際に自分で何か作成してみて理解できることの方が多いです。
特にUnityを使用することで目に見えて処理を確認することができますので、ぜひ色々なゲームやアプリを作成しながらクラスについて理解してみてください。
続けて第13回の記事に読む方はこちらをクリック
他の回の記事について気になる方はこちらをクリック
この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!