# ch07 — アクセス修飾子 (public / private / protected)

Source: https://php-school.pages.dev/topics/class/ch07-visibility/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: クラスの基本
Level: L3

Reference (official): https://www.php.net/manual/ja/language.oop5.php

## 本文

# ch07 — アクセス修飾子 (public / private / protected)

## 概要

アクセス修飾子は **「プロパティやメソッドに、どこから触ってよいか」を制限する仕組み** で、PHP には `public` / `private` / `protected` の 3 段階がある。`public` は外からも内からも自由に触れる、`private` は **そのクラスの中からしか** 触れない、`protected` は **そのクラスとその子クラスからのみ** 触れる、という違いがある。アクセスを絞ることで「外から壊されたくない内部データ」を守れる。

カプセル化 (encapsulation) と呼ばれるこの考え方の動機は **「外から自由に書き換えられると、データの整合性が保てない」** ことにある。例えば年齢を 0 以上に保ちたいクラスで `public $age` にしていると、外から `$user->age = -100;` と書かれて壊れる余地が残る。`private $age` にして `setAge(int $n)` のような公開メソッド越しにだけ更新を許せば、メソッドの中でバリデーションをかけられる。

実務でよく使うパターンは **「`private` プロパティ + `public` getter / setter」**。`getName()` で読み取り、`setName(string $s)` で書き込み、というインタフェースに統一しておくと、後から「読み取りを禁止する」「書き込み時にログを取る」のような変更を 1 か所だけで完結できる。`protected` は ch01 (継承) と組み合わせて初めて意味を持つので、本章では「子クラスから触れる修飾子」とだけ覚えておけば十分。

## 学習目標

- `public` / `private` / `protected` の違いを言える
- `private` プロパティは外から直接触れない (`$obj->prop` で失敗) と理解する
- `private` プロパティを `public` メソッド経由で取得するパターン (getter) を書ける

## 所要時間

スライド 4 分 + ドリル 1 問 = **10 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | `private $name` を `public function getName()` で取り出す |

> `protected` は **継承** と一緒に使う修飾子なので、本格的に使うのは L9。本 chapter では「子クラスから触れる」とだけ覚える。

## 採点

```bash
php scripts/grade.php topics/class/ch07-visibility/drill/01-getter/
```

## 関連チャプター

- [`ch03-properties`](../ch03-properties/) — `public` プロパティの読み書き (前提)
- [`ch05-this`](../ch05-this/) — `$this->name` で private にアクセス
- [`ch06-constructor`](../ch06-constructor/) — 初期化と private の組み合わせ
- [`../../09-class-advanced/ch01-inheritance`](../../09-class-advanced/ch01-inheritance/) — 継承と `protected`

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 8 / Chapter 7
  目的: public / private / protected の違いを理解し、private を public メソッド経由で扱える状態にする
  扱わない: 継承の本格利用 (L9) / static (L9) / readonly (L9)
  読み上げ時間目安: 3 分半〜4 分
-->

# `public` / `private` / `protected`

Lesson 8 / Chapter 7

---

## どこから触れるかを修飾子で決める

| 修飾子 | クラス内 | 子クラス | 外 (`$obj->prop`) |
|---|---|---|---|
| `public` | ◯ | ◯ | ◯ |
| `protected` | ◯ | ◯ | ✗ |
| `private` | ◯ | ✗ | ✗ |

- **`public`** … どこからでも触れる (ch01〜06 で使ってきたもの)
- **`private`** … そのクラスの中からだけ触れる
- **`protected`** … そのクラス + 子クラスから触れる (子クラスは L9)

---

## `private` は外から直接触れない

```php
<?php
class User {
    private string $name;

    public function __construct(string $name) {
        $this->name = $name;     // ◯ クラス内なので OK
    }
}

$u = new User("太郎");
echo $u->name;   // ❌ Error: 外から private には触れない
```

- 外からの `$u->name` は **エラーで停止する**
- 中からは `$this->name` で普通に触れる
- 「外に見せたくないデータ」を守りたい時に使う

---

## `public` なメソッド (getter) を用意して取り出す

```php
<?php
class User {
    private string $name;

    public function __construct(string $name) {
        $this->name = $name;
    }

    public function getName(): string {
        return $this->name;
    }
}

$u = new User("太郎");
echo $u->getName() . "\n";   // → 太郎
```

- プロパティは隠して、**メソッド経由で公開する**
- これが「カプセル化」と呼ばれる基本パターン
- 取得用メソッドは `get〇〇` という名前を付ける慣習がある

---

## なぜ `private` を使うのか

- **外から勝手に変えられない** → 整合性を守れる
  - 例: `age` を `-100` などの不正な値で直接書き換えられない
- **公開している場所が分かる** → 後で変更しやすい
  - 「`$obj->name` で読まれている所」を探す必要がなくなる
- **設計図を読みやすくなる** → `public` の一覧を見れば「外から使えるもの」が分かる

最初は全部 `public` でもよいが、慣れてきたら「外から触る必要が無いものは `private`」を意識する。

---

## このチャプターでできるようになること

✅ `public` / `private` / `protected` がどこから触れるかを表で言える
✅ `private` プロパティは外から `$obj->prop` で触れないと言える
✅ `private` を `public` メソッド (`getXxx`) 経由で取り出すパターンが書ける
✅ なぜ `private` を使うと安全になるかを 1 文で説明できる

→ ドリルへ
