[第11回] アクセス修飾子の使い方を学ぶ|Unityで学ぶC#入門
「Unityで学ぶC#入門」の連載第10回は「配列の使い方を学ぶ」でした。
第11回の今回はアクセス修飾子の使い方を学びます。
アクセス修飾子を学ぶことでプログラムの単純なミスや、不正なアクセスを防ぐことができるようになります。
また、今回は入門記事ですので基本的なアクセス修飾子である「public」と「private」の違いに着目して解説していきます。
クラスの考え方を学ぶ前に知っておくと、後々役に立ちますのでぜひこ参考ください。
アクセス修飾子とは
アクセス修飾子とは、クラス(現状スクリプトという認識で構いません)や、そのクラス内のメソッド、変数がどこからアクセス(値の変更や参照)をすることができるかを決定するものです。
↓アクセス修飾子イメージ
これによって、他のオブジェクトからアクセスして欲しくない変数やメソッドを決定することができます。
誤って他のオブジェクトから変数の値を操作してしまう処理を記述したときに、アクセス修飾子を記述しておけばエラーを吐き出すため修正することができます。
アクセス修飾子を記述していないと、どこが間違っているのか発見するのに時間がかかってしまうこともあります。このような問題を改善するためにも普段からアクセス制御を意識してプログラムを書くことをおすすめします。
アクセス修飾子の種類
C#のアクセス修飾子の種類についてご紹介します。
C#の修飾子は以下6種類の記述方法があります。
修飾子 | 機能 |
public | 無制限のアクセスを許可 |
private | コンテナである型にアクセスを制限 |
internal | 現在のアセンブリにアクセスを制限 |
protected | コンテナであるクラス、そこから派生した型にアクセスを制限 |
protected internal | 現在のアセンブリ、包含クラスから派生した型にアクセスを制限 |
private protected | 包含クラス、包含クラスから派生した型にアクセスを制限 |
なし | =private |
難しい用語がたくさん出てきますが、今回はpublic,privateのみを詳しく解説していきます。
そもそもアクセス修飾子は記述しないとプログラムを完成させることができないわけではなく、あくまで保守性や頑健性を高めるプログラミング技術の一つです。
「internal」「protected」はクラスやアセンブリといったプログラムの構造的な仕組みを理解してから利用しないと、かえってエラーを引き起こす可能性がありますので注意してください。
アクセス修飾子の使い方
アクセス修飾子の使い方をご紹介します。
使い方はいたってシンプルで、変数やメソッドの前に記述するだけです。
↓コード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Sample1 : MonoBehaviour { //アクセス修飾子を利用した変数定義 private int num1; public int num2; //アクセス修飾子を利用した変数定義 private void method1(){ //処理を記述 } public void method2(){ //処理を記述 } } |
このように記述するだけでアクセスを簡単に制御することができます。
また、以下のように記述するとエラーが発生します。
↓エラーコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Sample1 : MonoBehaviour { //アクセス修飾子を利用した変数定義 //エラー例1:型宣言の後にアクセス修飾子を記述する int private num1; //エラー例2:一番最後にアクセス修飾子を記述する int num2 private; } |
例のようにアクセス修飾子を型宣言の後ろや、変数名の後ろに置くとエラーが発生しますのでご注意ください。
変数定義に関する詳しい情報は以下記事をご参考ください。
参考記事)変数の使い方を学ぶ
「public」と「private」の違い
「public」と「private」の違いについてご紹介します。
まず「public」はアクセスを一切制限しません。つまり、「public」な変数はどのプログラムからでも参照、変更が可能になります。
逆に「private」は記述されたスクリプト以外からのアクセスをできないように制限します。
↓「public」「private」違いイメージ
上記の図のように「public」な変数やメソッドは他スクリプト(他クラス)からアクセスが可能ですが、「private」な変数やメソッドは他スクリプトからアクセスができません。
また、「public」「private」どちらの修飾子も同スクリプト内からのアクセスは可能です。
このように他スクリプトからのアクセスを避けたいときに「private」を使用します。
アクセス修飾子の使用例
アクセス修飾子の使用例をご紹介します。
ここで少しだけクラスの仕組みを利用したプログラムを記述しますが、よくわからない記述は読み流してしまって問題ありません。
では以下のスクリプト「Sample1」と「Sample2」を記述して、「Sample2」のみを任意のゲームオブジェクトに取り付けてください。
↓Sample1.cs
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Sample1 { //privateなint型の変数nums private int num1; private int num2; //publicなstring型の変数name public string name; //numsの値をセットするメソッド public void setNum(int num1, int num2){ //numsに引数の値を代入 //this.〇〇とすることで自分自身の変数を指定することが可能 this.num1 = num1; this.num2 = num2; } //num1の値を取得するメソッド public int getNum1(){ return num1; } //num2の値を取得するメソッド public int getNum2(){ return num2; } } |
↓Sample2.cs
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Sample2 : MonoBehaviour { //Sample1クラスの変数を定義 //ここではSample1スクリプトをSample2で使用するための記述方法という認識で問題ありません Sample1 sample1; //Sample1のnums値を持ってくるための変数 int num1_check; int num2_check; // Start is called before the first frame update void Start() { //Sample1のインスタンス生成 //ここではSample1スクリプトをSample2で使用するための記述方法という認識で問題ありません sample1 = new Sample1(); //Sample1のnameの値を変更する sample1.name = "XR-Hub"; //Sample1のnumsの値を変更する sample1.setNum(10,20); //変更した値をgetNums()でnums_checkに代入する num1_check = sample1.getNum1(); num2_check = sample1.getNum2(); //変更した値を確認する Debug.Log("name = [" + sample1.name + "],num1 = [" + num1_check + "],num2 = [" + num2_check + "]"); } } |
↓実行結果
ではプログラムを確認していきます。
Sample1では「private」なint型の変数と「public」なstring型の変数を定義しています。
1 2 3 4 5 6 |
//privateなint型の変数nums private int num1; private int num2; //publicなstring型の変数name public string name; |
「private」なint型の変数「num1」と「num2」はそれぞれSample1内からのみアクセスすることができます。
そこで「public」なメソッド「setNums()」「getNum1()」「getNum2()」を定義することで、他スクリプトから「num1」「num2」それぞれに値を格納、参照することができる仕組みにしています。(getter関数とsetter関数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//numsの値をセットするメソッド public void setNum(int num1, int num2){ //numsに引数の値を代入 //this.〇〇とすることで自分自身の変数を指定することが可能 this.num1 = num1; this.num2 = num2; } //num1の値を取得するメソッド public int getNum1(){ return num1; } //num2の値を取得するメソッド public int getNum2(){ return num2; } |
「public」なstring型の変数「name」は、他スクリプトからアクセスすることが可能なので値を変更、参照するためのメソッドを記述する必要はありません。
次にSample2を確認します。
Sample2ではSample1クラスのインスタンスを生成しています。(意味がわからなくても問題ありません)
1 2 |
Sample1 sample1; sample1 = new Sample1(); |
9行目と20行目でSample1を扱うための記述をしているだけですので難しく考える必要はありません。
それ以外ではアクセス制御に気をつけながら値を変更、参照しています。
23行目ではSample1の変数nameを直接変更しています。
1 2 |
//Sample1のnameの値を変更する sample1.name = "XR-Hub"; |
対して26行目ではSample1の変数num1,num2をメソッドsetNums()を使用して間接的に変更しています。
1 2 |
//Sample1のnumsの値を変更する sample1.setNum(10,20); |
値を参照する際も同じで、nameは直接参照することができますが、num1,num2はgetter関数を用いて値を参照します。
1 2 3 |
//変更した値をgetNums()でnums_checkに代入する num1_check = sample1.getNum1(); num2_check = sample1.getNum2(); |
これによって、クラス間(スクリプト間)の値の受け渡しを適切に行うことが可能になります。
num1,num2の値をnameと同じように直接変更、参照しようとするとエラーが発生しますのでぜひ確認してみてください。
まとめ
いかがでしたでしょうか。
今回はC#のアクセス修飾子の使い方についてご紹介してきました。
アクセス修飾子はプログラムを複数人で記述するときにとても役に立ちます。
他者が記述した変数やメソッドを操作しようとしたときに、事前に制御しておくことでエラー発生を防いだり、誤作動を防ぐことができます。
保守性を考えたときにアクセス修飾子はとても大切ですので、普段のプログラミングから意識して修飾子を記述するようにしましょう。
続けて第12回の記事に読む方はこちらをクリック
他の回の記事について気になる方はこちらをクリック
この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!