public / private / protected アクセス修飾子と readonly
最終更新:2026-10-22
public / private / protected アクセス修飾子と readonly
アクセス修飾子はメンバーの可視性を制御します。public(デフォルト、内外どこからでもアクセス可)、private(クラス内部のみ)、protected(クラス内部とサブクラス)。これらはコンパイル時の制約であり、カプセル化のミスは実行時にデータが壊れてからではなく、コードを書いている時点でエラーになります。
| グループ | 関数とクラス |
|---|---|
| 種類 | 構文 |
| strict モード | 不要 |
ℹ️ 説明 エディタは TypeScript を JavaScript にトランスパイルして実行します(型チェックなし)。型チェック結果は各サンプルの出力を参照してください。
📝 構文
class BankAccount {
public owner: string; // public がデフォルト。明示するのは意図を表すため
private balance: number; // クラス内部からのみ読み書き可能
constructor(owner: string, initial: number) {
this.owner = owner;
this.balance = initial;
}
deposit(amount: number): void { this.balance += amount; }
getBalance(): number { return this.balance; }
}
⚙️ パラメータ
| public | デフォルトの修飾子:どこからでもアクセス可能。明示的に書くと設計意図を表せます |
|---|---|
| private | このクラス自身のメソッド内からのみアクセス可能。外部やサブクラスからのアクセスはコンパイルエラーになります |
| protected | このクラスとサブクラスから使え、外部からは使えません——サブクラスのために残す「制御された拡張点」です |
戻り値:修飾子はメソッドの戻り値型を変えず、「誰が呼べ、誰が読み書きできるか」だけを制約します。
▶ サンプル
下のコードを編集して「試す」を押すと、トランスパイル実行結果を確認できます:
出力:
Mia: 150
(トランスパイル後の実行出力。外部から直接 acct.balance を書き換えるとコンパイルエラーになります——クラス内部のメソッド経由でのみ変更できます)
💡 ポイント
ℹ️ 説明 private/protected は純粋にコンパイル時のものです。トランスパイル後もフィールドはオブジェクト上に残ります(実行時にも acct.balance は取得できます)。実行時の隔離が必要なら JS のプライベートフィールド #balance を使います。
ℹ️ 説明 同じクラスのインスタンス同士は互いのプライベートメンバーにアクセスできます(equals(other: BankAccount) の中で other.balance を読むなど)。これは設計上の仕様で、違反ではありません。
⚠️ 注意 トランスパイル後には private は無効になるので、「安全性」をそれに期待してはいけません。防げるのは無意識の誤用であって、悪意あるアクセスではありません。
🏷️ 関連関数とクラス
💡 関連ケース
ケースは今後追加予定です。
📚 関連チュートリアル
❓ よくある質問
Q private と #プライベートフィールドの違いは何ですか?
A private は TS のコンパイル時検査(実行時には回避可能)。#field は JS の言語レベルのプライベート(実行時に本当にアクセスできません)。新しいコードでは # を優先し、TS の型システムと深く連携させたい場面では private を使うとよいでしょう。
Q protected はいつ使いますか?
A サブクラスに「制御された拡張点」を残すときです。テンプレートメソッドパターンの親クラスのフックメソッドや、サブクラスが読む必要のある内部状態など。public より締めて private より緩い位置づけです。
Q getter/setter と public フィールドはどう使い分けますか?
A 読み書きに副作用(バリデーション、キャッシュ、派生値)が必要なら get/set を使います。純粋なデータの格納なら public フィールドのままでよく、すべてのフィールドをアクセサで包むべきではありません。