public と private は「どこからでも」と「同じクラスだけ」の 2 択でした。継承を使うと、派生クラスには見せたいが外部には隠したいメンバーが出てきます。この用途に使うのが protected です。
protected のアクセス範囲を説明できるprivate / public / protected の 3 つを対比できるprotected の到達範囲を確認できるinternal の意味を説明できる| 修飾子 | アクセス可能な範囲 |
|---|---|
public |
どこからでもアクセスできる |
private |
同じクラス内のみ |
protected |
同じクラス内、および派生クラス内 |
internal |
同じアセンブリ(プロジェクト)内 |
private と protected の違いは「派生クラスからアクセスできるかどうか」です。
protected の基本書式:protected メンバーの定義
1
protected 型 メンバー名;
1
2
3
4
5
6
7
8
9
10
11
12
class A
{
protected void M() { Console.WriteLine("A.M"); }
}
class B : A
{
public void N()
{
M(); // ✅ 派生クラスから呼べる
}
}
A の外側から M() を直接呼ぶことはできません。
1
2
3
A a = new A();
// ❌ コンパイルエラー: protected メンバーは外部からアクセスできない
// a.M();
protected メンバーは継承チェーン全体を通じてアクセスできます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A
{
protected void M() { Console.WriteLine("A.M"); }
}
class B : A
{
public void CallM()
{
M(); // ✅ B から A の protected メンバーにアクセスできる
}
}
class C : B
{
public void CallM2()
{
M(); // ✅ C からも A の protected メンバーにアクセスできる
}
}
1
2
A.M
A.M
internal についてinternal は同じアセンブリ(同一プロジェクト)内であればどこからでもアクセスできます。
1
2
3
4
internal class A
{
internal void M() { }
}
Unity のスクリプトでは通常 1 つのアセンブリ内で開発するため、internal の効果は public に近くなります。複数アセンブリ(DLL 分割・パッケージ分割)をまたぐ場合に意味を持ちます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class A
{
protected void M() { }
}
// ❌ NG: 継承関係にない外部クラスからは呼べない
class X
{
void Test()
{
A a = new A();
// a.M(); // コンパイルエラー
}
}
// ✅ OK: 派生クラスの内側から呼ぶ
class B : A
{
void Test()
{
M(); // 呼べる
}
}
protected は「同じクラス内と派生クラス内」からアクセス可能private は「同じクラス内のみ」。派生クラスからも呼べないprotected は継承チェーン全体を通じて有効internal は同じアセンブリ内からアクセス可能private と protected の違いを一文で説明してください。次のコードはコンパイルできますか?
1
2
3
4
5
6
7
class A
{
protected void M() { }
}
A a = new A();
a.M();
class C : B のとき、B が A を継承しており A に protected void M() があります。C から M() は呼べますか?private は同じクラス内のみ。protected は同じクラス内と派生クラス内からアクセスできます。protected メンバーはクラスの外部から直接呼べません。protected は継承チェーン全体に届きます。オーバーライドとポリモーフィズム では、virtual・override を使って派生クラスでメソッドの動作を変える仕組みを学びます。