初めに
C# はオブジェクト指向型のプログラミング言語です。本記事では、private や public などアクセス修飾子に関わるカプセル化と呼ばれる概念について、まとめます。また、継承やアセンブリについても簡単に説明しています。
Index
オブジェクト指向型について
C#言語はオブジェクト指向型のプログラミング言語です。オブジェクト指向とは、
のことです。
カプセル化
オブジェクト指向では "カプセル化" と呼ばれる考え方に基づいてプログラミングを行います。
カプセル化とは、
です。
オブジェクトは中身(内部実装)がどうなっているのかを隠蔽し、 可能な操作(関数、メソッド)と属性(プロパティ)のみを公開することで、外部からの直接的なアクセスを防ぎ、バグの発生を抑制できます。
アクセシビリティ・アクセス修飾子
変数や関数には、アクセシビリティ(Accessibility: アクセスできる度合い)があります。private や public などアクセス修飾子をつけることでアクセシビリティを制御することが出来ます。
アクセス修飾子 | 説明 |
---|---|
public | どこからでもアクセス可能 |
protected internal | 同一プロジェクト内のクラス内部、または、派生クラスの内部からのみアクセス可能 |
protected | クラス内部と、派生クラスの内部からのみアクセス可能 |
internal | 同一プロジェクト内のクラスからのみアクセス可能 |
private protected | 同一プロジェクト内のクラス内部、かつ、派生クラスの内部からのみアクセス可能 |
private | クラス内部からのみアクセス可能 |
※アクセス修飾子を省略した場合は、private になります。
※派生については下記の継承で、アセンブリについてはプロジェクトの分割で説明します。
アクセス修飾子の付け方
アクセス修飾子は変数や関数の定義の前につけます。
//変数の場合 public int number = 1; //関数の場合 private void Method() { Debug.Log("この関数はprivateです"); }
継承・派生
継承(inheritance)とは、
です。派生(derivation)とも呼ばれます。
継承は集合の包含関係があるものを表現するときに使います。
「動物」と「犬」という2つのクラスを例に用いて説明します。この2つのクラスについて、次の関係が成り立ちます。
- 「犬」⊂「動物」:「犬」は「動物」に含まれる
- 「動物」⊄「犬」:「動物」は「犬」に含まれない
「犬」は「動物」に含まれるので、「動物」の属性を備えています。
継承関係
2つのクラス A, B において、 B ⊂ A (A が B を含む)が成り立つ関係にあるとき、この関係を継承関係と呼び、B は A を継承する(B は A から派生する)といいます。また、このとき、A を基底クラス(base class、super class)といい、B を派生クラス(derived class、sub class)とよびます。
クラスの継承の仕方
次のように記述することで、クラスの継承をすることができます。
//クラスの継承の仕方 // sub には派生クラス名を, base には基底クラス名を記述 class sub : base { //派生クラスの定義 }
(例)
class Animal { private string name; //名前 protected int age; //年齢 } class Dog : Animal { public string breed; //品種 }
派生クラスは基底クラスとして扱えますが、基底クラスは派生クラスとして扱えません。つまり、派生クラスのインスタンスを基底クラスの変数に代入することはできますが、基底クラスのインスタンスを派生クラスに代入することはできません。
(例)
//Animalは基底クラス Animal a1 = new Animal(); a1.name = "太郎"; a1.age = 8; //Dogは派生クラス Dog d1 = new Dog(); d1.name = "はち"; //派生クラスは基底クラスの変数を利用できる d1.age = 6; d1.breed = "shiba"; //Dog は Animal の派生クラスなのでAnimal として扱える Animal a2 = d1;
(できない例)
//これはエラーになります。 Dog d2 = a1;
派生クラスである「犬」は「動物」なので、基底クラスの「動物」としても扱えますが、「動物」であっても「犬」とは限らないので、基底クラスを派生クラスとして扱うことはできません。
object 型
object 型は、すべてのクラスとすべての値型・参照型の基底クラスです。
基底クラスを指定せずに作成した型はすべて object 型を継承することになります。
object 型で定義されている関数には、以下のものがあります。
返り値 | 関数 | 説明 |
---|---|---|
bool | Equal | 引数内のオブジェクトが等しいかどうか |
int | GetHashCode | オブジェクトに関連付けられたハッシュコードを返す |
Type | GetType | オブジェクトのタイプを返す |
string | ToString | オブジェクトを表す文字列を返す |
protected
protected はクラスとそのクラスを継承する派生クラス内からアクセス可能です。
(例)
class Animal { public string name; //名前 protected int age; //年齢 private string habitat; //生息地 } class Drived : Animal { void Test() { name = "Jiro"; //ok age = 10: //ok(protectedは派生クラスからアクセスできる habitat = "Japan"; //エラー(privateは派生クラスからアクセスできない) } }
sealed(継承禁止)
クラスを定義するときに sealed をつけることで、継承を禁止することができます。
//継承禁止のクラスの定義 sealed class Base() { //基底クラス }
アセンブリ
アセンブリとは
アセンブリ(部品、組み立て部品)とは、
です。アセンブリは exe や dll ファイル として実行されます。
基本的に C# では、プロジェクト内の複数のソースコードのコンパイル結果を1つのファイルにまとめて出力されます。その出力されたファイルがアセンブリになります。
プロジェクトを分割する場合
プロジェクトを分割しない限り internal のようなアセンブリ間のアクセシビリティを考える必要はありません。
しかし、次のようなプロジェクトを分割したい場合がでてきます。
このように、プロジェクトを分割する必要がでた場合はそれぞれのプロジェクト間での依存関係を考える必要がでてきます。
Unity の場合
Assembly Definition(アセンブリ定義)という機能があります。これによりC# のアセンブリ(ビルドファイル)を分割することができます。
docs.unity3d.com
参考
最後に
public、protected、private の違いと継承だけでも使えるようにしたいものです。