┗ グローバル名前空間
┗ 名前空間(namespace)
┗ 型(クラス)空間
5つのアクセシビティ
PUBLIC: 制限されない
PROTECTED: クラス内部から + 派生クラス内部から
INTERNAL: 同一プログラムから可
PROTECTED INTERNAL:
PRIVATE: クラス内部から
デフォルトのアクセシビティ
型(クラス): INTERNAL
型のメンバ: PRIVATE
付けることのできるアクセシビティ
型(クラス): public、internal
┃
┣ 型のメンバ: public、protected、internal、protected internal、private
┃ ┃
┃ ┣ インターフェースのメソッド: 定義側は表記不要。実装側はpublicのみ
┃ ┃
┃ ┗ 抽象メソッド: private以外は大丈夫 (継承元、継承先で同じアクセシビティにする必要がある)
┃ ┗ 実装側でoverrideする必要あり。
┃
┗ 構造体の子メンバ: public、internal、private
アクセシビティについて実験
private・protectedはクラス内部からしかアクセスできない。インスタンス生成して class.method()などの様に直接使えない。protectedは派生クラスの内部からもアクセスできる。
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 |
class Program { static void Main(string[] args) { BaseAction b = new BaseAction(); Console.Write(b.age.ToString());// 20 // 基底クラスのメンバ変数。 Taro t = new Taro(); Console.Write(t.age.ToString());// 20 // サブクラスで同じメンバ変数を参照。 t.sum(); // サブクラスのメソッドでメンバ変数の値を変更。 Console.Write(b.age.ToString());// 20 // サブクラスでの変更は基底クラスに影響していない。 Console.Write(t.age.ToString());// 21 Console.ReadKey(); } } class BaseAction { internal int age = 20; } class Taro: BaseAction { internal void sum() { this.age = 21; } } |
継承はあくまでもクラス(ひな形の)コピーであってインスンタス生成後にお互いに影響を与えない。
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 |
class Program { static void Main(string[] args) { dog d = new dog(); d.bow(); // d.jamp(); ここはエラー。 // 基底クラスでprivateなメソッドはサブクラスで呼び出せない。 // 継承や実装でアクセシビティは引き継がない。 } } class animal { public void bow() { Console.Write("bow bow"); Console.ReadKey(); } private void jamp() { } } class dog : animal { } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class Program { static void Main(string[] args) { Human h = new Human(); // Taro t = new Taro(); ここはエラー。 Human.Taro t = new Human.Taro(); t.SayHello(); // 入れ子のクラスのインスタンス生成。 } } internal class Human { // クラスは入れ子にできる。 internal class Taro { public void SayHello() { Console.Write("Hello"); Console.ReadKey(); } } } |
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 |
class Program { static void Main(string[] args) { int age = 20; if (true) { Console.Write(age.ToString()); Console.ReadKey(); // ローカル変数の場合、下位から上位のスコープを参照することができる。 } } } public class Human { private string FirstName = "taro"; private class Taro // クラスが入れ子になっている。 { // FirstName = "hanako"; ここはエラー。 // クラスの入れ子のスコープの関係はローカル変数とは違う。 // クラスのメンバーのスコープはクラス内に限られる。 // publicやprivateなどのアクセシビティはスコープではなく // そのクラスのメンバーが、他のクラスからどう見えるかを定義するもの。 } } |
通常、クラスを入れ子にはしないが、クラスのスコープは越えられない。アクセシビティは誰に見せるかを定義するもので、メンバは、アクセシビティで許可した範囲からメッセージを受け付ける。
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 |
class Program { static void Main(string[] args) { Taro t = new Taro(); t.say(); Console.ReadKey(); } } static class TestClass { static internal int prev = 1; static internal int next = 2; static internal int home = prev * next; } class BaseAction { protected int Age = 20; } class Taro : BaseAction { internal int prev = 1; internal int next = 2; // internal int home = prev * next; ここはエラー。 // 同一のクラスでメンバ変数同士で演算できない。 // staticなクラスなら可能。TestClass参照。 // 同じ理由によりメンバ変数に継承元のメンバ変数も代入はできない。 // internal int Birth = this.Age; ここはエラー。 internal void say() { // これは継承元のprotectedフィールドを出力している。 Console.Write(Age.ToString()); int answer = this.prev * this.next; // メンバ変数もメソッドの中での演算なら可能。 } } |
クラス定義領域では、メンバ変数同士での演算はできない。staticなクラスなら可能。クラス定義領域はインスタンス生成に評価されるため。
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 |
class Program { static void Main(string[] args) { Status.age = "20"; Console.Write(Status.age); // 20 Test t = new Test(); Console.Write(Status.age); // 22 // staticなクラスのためtestクラスのコンストラクタの影響を受けている。 Console.ReadKey(); } static class Status { internal static string age = "0"; } //通常のクラスはインスタンス生成後にインスタンスとクラスお互いに影響しない。 class Test: BaseClass { public Test() { Status.age = "22"; } } class BaseClass { public BaseClass() { Console.Write("This is BaseClass"); } } } |
コンストラクタをprivateにするとインスタンス生成できないクラスになる。
基底クラスのコンストラクが実行され、次にサブクラスのコンストラクタが実行される。
上の例では、”20″のあと”This is BaseClass”と表示される。