フィールドをすべて public にしておくと、クラスの外から自由に書き換えられてしまいます。
1
2
Player p = new Player("Alice", 100);
p.hp = 999999; // ゲームバランスを無視した書き換えが可能
アクセス修飾子はフィールドやメソッドへの「アクセス可能な範囲」を制限する仕組みです。外から触ってよい部分だけを公開し、内部の詳細を隠すことをカプセル化と呼びます。カプセル化によってクラスの誤用を防ぎ、後から内部実装を変更しやすくなります。
public と private の違いを説明できるprivate フィールドをメソッド経由で操作できるpublic と private| 修飾子 | アクセス可能な範囲 |
|---|---|
public |
どこからでもアクセスできる |
private |
同じクラス内からのみアクセスできる |
書式:フィールドの定義(修飾子あり)
1
アクセス修飾子 型 フィールド名;
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
class Player
{
public string name; // クラスの外から読み書きできる
private int _hp; // クラスの外から直接触れない
private int _maxHp;
public Player(string playerName, int initialHp)
{
name = playerName;
_hp = initialHp;
_maxHp = initialHp;
}
public void TakeDamage(int damage)
{
if (damage < 0) { return; } // 不正な値を弾く
_hp = _hp - damage;
if (_hp < 0) { _hp = 0; }
Console.WriteLine($"{name} が {damage} ダメージ。残りHP={_hp}");
}
public void Heal(int amount)
{
if (amount < 0) { return; }
_hp = _hp + amount;
if (_hp > _maxHp) { _hp = _maxHp; }
Console.WriteLine($"{name} が {amount} 回復。残りHP={_hp}");
}
public int GetHp()
{
return _hp;
}
}
1
2
3
4
5
6
Player p = new Player("Alice", 100);
p.TakeDamage(30);
p.Heal(20);
Console.WriteLine($"現在HP={p.GetHp()}");
// p._hp = 999; // ❌ コンパイルエラー: private フィールドには外からアクセスできない
1
2
3
Alice が 30 ダメージ。残りHP=70
Alice が 20 回復。残りHP=90
現在HP=90
_hp を private にすることで TakeDamage と Heal だけが値を変更できるようになりました。不正な値のチェックをメソッド内に集約でき、バグを防ぎやすくなります。
📌 C# では
privateフィールドの命名に_camelCase(アンダースコア+小文字始まり)を使うことが多いです。
アクセス修飾子を省略した場合のデフォルトは次のとおりです。
| 要素 | 省略時のデフォルト |
|---|---|
| クラスのメンバー(フィールド・メソッド) | private |
| クラス自体(トップレベル) | internal |
意図しない公開を防ぐため、フィールドには明示的に private と書く習慣をつけましょう。
Unity や中規模以上のプロジェクトでは以下の修飾子も登場します。現段階では存在だけ確認してください。
| 修飾子 | アクセス可能な範囲 |
|---|---|
internal |
同じアセンブリ(プロジェクト)内からのみ |
protected |
同じクラスおよびそのクラスを継承したクラスから |
protected internal |
protected と internal の和(どちらかを満たせばOK) |
private protected |
同じアセンブリ内かつ派生クラスのみ |
internal は複数プロジェクトを組み合わせる場面で、protected は継承(派生クラス)の学習後に詳しく扱います。
public — どこからでもアクセス可能。外部に公開したいメソッドや情報に使うprivate — クラス内部からのみアクセス可能。フィールドは基本的に private にするprivate 扱いになる次のコードはコンパイルエラーになりますか? 理由とともに答えてください。
1
2
3
4
5
6
7
8
9
class Box
{
private int _value;
public Box(int v) { _value = v; }
}
Box b = new Box(10);
Console.WriteLine(b._value);
下のクラスの _score フィールドを private に変更し、スコアを加算する AddScore(int points) メソッドと現在のスコアを返す GetScore() メソッドを追加してください。
1
2
3
4
5
class Player
{
public string name;
public int _score; // ← private に変える
}
(応用)private フィールド _level(初期値 1)と _exp を持つ Character クラスを定義してください。AddExp(int amount) メソッドで _exp を加算し、100 以上になったら _level を 1 上げて _exp を 0 にリセットするよう実装してください。
コンパイルエラーになる。_value は private であり、クラスの外(Box クラスの外)からアクセスできない。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Player
{
public string name;
private int _score;
public void AddScore(int points)
{
_score = _score + points;
}
public int GetScore()
{
return _score;
}
}
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
class Character
{
public string name;
private int _level;
private int _exp;
public Character(string charName)
{
name = charName;
_level = 1;
_exp = 0;
}
public void AddExp(int amount)
{
_exp = _exp + amount;
if (_exp >= 100)
{
_level = _level + 1;
_exp = 0;
Console.WriteLine($"{name} がレベル {_level} になった!");
}
}
public string GetStatus()
{
return $"{name}: Lv={_level}, EXP={_exp}";
}
}
プロパティ(get / set)を使うと、private フィールドへの読み書きをより簡潔に安全に記述できます。
次のページで学びましょう → プロパティ