ch01 8章中 1章目

ch01 — 継承 (extends)

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch01 — 継承 (extends)」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch01 — 継承 (extends)」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch01 — 継承 (extends)」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

なぜ継承が要るか

UserAdminUser9 割同じ機能 を持つ。email / login() は両方に必要で、AdminUser だけが追加で deleteAll() を持つ。これを 2 つのクラスに コピペで書くと、ログイン処理を直したいときに 2 箇所直す ことになる。継承はこの重複を吸収する仕組み。

extends の書き方

class 子 extends 親 と書くと、親のプロパティとメソッドをそのまま引き継げる。

class User {
    public string $email;
    public function login(): void {
        echo "{$this->email} がログインしました\n";
    }
}
class AdminUser extends User {
    public function deleteAll(): void {
        echo "{$this->email} が全データを削除しました\n";
    }
}

AdminUserlogin() を書いていないのに呼べる。

is-a 関係で使う

継承の判断基準は 「子は親の役割を全部果たせるか」AdminUser is a User (管理者もユーザー) は自然なので OK。一方 Order is a PaymentGateway (注文は決済ゲートウェイ) は不自然なので、こちらはプロパティで PaymentGateway を持つ「has-a 関係」にする。

PHP は単一継承

PHP では 1 つのクラスは親を 1 つしか持てない (extends A, B は書けない)。複数の能力を組み合わせたいときは、後の章で扱う インターフェース (ch05) で契約を複数実装する形にする。

深い継承は避ける

継承は強力だが、親を直すとすべての子に波及する副作用も大きい。現代では 1〜2 段で済ませる 設計が主流。3 段以上の継承ツリーを作る前に「これは継承でいいのか」を疑うのがよい。

学習目標

  • class 子 extends 親 で親クラスのプロパティとメソッドを引き継げる
  • 子クラスで新しいメソッドを追加できる
  • 「共通機能は親、権限固有の機能は子」という分け方を理解する

ドリル

no 内容
01 User を継承した AdminUserdeleteAll() を追加する

解説スライド 全 8 枚

右の ボタン キー(またはスワイプ)で次のスライドに進めます。 下の「縦表示」を開くと全スライドを一気に読めます。

  1. 継承 (extends)

    Lesson 9 / Chapter 1

  2. ゴール

    ユーザーの種類 (管理者 / 一般) ごとにクラスを分けたい。

    User (親)         ← 共通: name, login()
     ├── AdminUser    ← 管理者だけ: deleteAll()
     └── GuestUser    ← 閲覧のみ

    共通部分を 親にまとめる、固有部分を 子に書く ができるようにする。

  3. 似たクラスを 2 つ書くと重複する

    <?php
    class AdminUser {
        public string $name;
        public function login() {
            echo "{$this->name} がログインした\n";
        }
    }
    
    class GuestUser {
        public string $name;
        public function login() {
            echo "{$this->name} がログインした\n";
        }
    }
    • namelogin() も同じ
    • 後から仕様変更すると 両方 直す必要がある
  4. extends で共通部分を親クラスにまとめる

    <?php
    class User {
        public string $name;
        public function login() {
            echo "{$this->name} がログインした\n";
        }
    }
    
    class AdminUser extends User {
    }
    • User親クラス (スーパークラス)
    • AdminUser子クラス (サブクラス)
    • 子は親の namelogin() をそのまま使える
  5. 継承したメソッドを呼べる

    <?php
    $u = new AdminUser();
    $u->name = "tanaka";
    $u->login();

    実行結果:

    tanaka がログインした
    • AdminUser には login() を書いていないが、親 User のものが使える
    • プロパティ name も同様
  6. 子クラスで新しいメソッドを追加できる

    <?php
    class AdminUser extends User {
        public function deleteAll() {
            echo "{$this->name} が全データを削除した\n";
        }
    }
    
    $u = new AdminUser();
    $u->name = "tanaka";
    $u->login();       // 親から継承
    $u->deleteAll();   // 子で追加 (管理者だけの操作)
    • 子クラスにしか無いメソッドは、親 (User) や別の子 (GuestUser) では呼び出せない
    • 本番では権限チェックも別途必要だが、ここではクラスでの分離に集中する
  7. 継承は「共通 → 親、固有 → 子」

    User (親)
      ├── name
      └── login()
         ↑ 継承
    AdminUser (子)
      └── deleteAll()    ← 管理者だけ持つ
    GuestUser (子)
      └── (閲覧のみ・追加メソッドなし)
    • 共通部分を親に置けば、変更が 1 箇所で済む
    • 子クラスは「親 + 自分の追加分」を持つ
  8. このチャプターでできるようになること

    class 子 extends 親 で継承できる ✅ 親クラスのプロパティ・メソッドを子で使える ✅ 子クラス独自のメソッドを追加できる ✅ ロール別 (管理者 / 一般) の共通処理を親にまとめる発想ができる

    → ドリルへ

1 / 8
📜 スライドを全部一気に読む(縦表示)

Lesson 9 / Chapter 1


ゴール

ユーザーの種類 (管理者 / 一般) ごとにクラスを分けたい。

User (親)         ← 共通: name, login()
 ├── AdminUser    ← 管理者だけ: deleteAll()
 └── GuestUser    ← 閲覧のみ

共通部分を 親にまとめる、固有部分を 子に書く ができるようにする。


似たクラスを 2 つ書くと重複する

<?php
class AdminUser {
    public string $name;
    public function login() {
        echo "{$this->name} がログインした\n";
    }
}

class GuestUser {
    public string $name;
    public function login() {
        echo "{$this->name} がログインした\n";
    }
}
  • namelogin() も同じ
  • 後から仕様変更すると 両方 直す必要がある

extends で共通部分を親クラスにまとめる

<?php
class User {
    public string $name;
    public function login() {
        echo "{$this->name} がログインした\n";
    }
}

class AdminUser extends User {
}
  • User親クラス (スーパークラス)
  • AdminUser子クラス (サブクラス)
  • 子は親の namelogin() をそのまま使える

継承したメソッドを呼べる

<?php
$u = new AdminUser();
$u->name = "tanaka";
$u->login();

実行結果:

tanaka がログインした
  • AdminUser には login() を書いていないが、親 User のものが使える
  • プロパティ name も同様

子クラスで新しいメソッドを追加できる

<?php
class AdminUser extends User {
    public function deleteAll() {
        echo "{$this->name} が全データを削除した\n";
    }
}

$u = new AdminUser();
$u->name = "tanaka";
$u->login();       // 親から継承
$u->deleteAll();   // 子で追加 (管理者だけの操作)
  • 子クラスにしか無いメソッドは、親 (User) や別の子 (GuestUser) では呼び出せない
  • 本番では権限チェックも別途必要だが、ここではクラスでの分離に集中する

継承は「共通 → 親、固有 → 子」

User (親)
  ├── name
  └── login()
     ↑ 継承
AdminUser (子)
  └── deleteAll()    ← 管理者だけ持つ
GuestUser (子)
  └── (閲覧のみ・追加メソッドなし)
  • 共通部分を親に置けば、変更が 1 箇所で済む
  • 子クラスは「親 + 自分の追加分」を持つ

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

class 子 extends 親 で継承できる ✅ 親クラスのプロパティ・メソッドを子で使える ✅ 子クラス独自のメソッドを追加できる ✅ ロール別 (管理者 / 一般) の共通処理を親にまとめる発想ができる

→ ドリルへ

この章で取り組む 演習問題の流れ (1ステップ)
  1. 01 ドリル 01 — User を継承した AdminUser README.md starter.php answer.php

演習問題の詳細

この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。

ドリル 01 — User を継承した AdminUser

やること

User クラスを定義してください。

  • プロパティ email (string)
  • メソッド login()"{email} がログインしました" を 1 行出力する

次に User を継承した AdminUser クラスを定義してください。

  • メソッド deleteAll()"{email} が全データを削除しました" を 1 行出力する

最後に AdminUser のインスタンスを作って email"admin@example.com" を入れ、login()deleteAll() を順に呼んでください。

期待される出力

admin@example.com がログインしました
admin@example.com が全データを削除しました

補足: 実務ではパスワード照合・セッション発行・権限チェックが入りますが、ここでは「継承で機能を引き継ぐ」一点だけにフォーカスします。

ヒント

  • class AdminUser extends User { ... }
  • $a = new AdminUser();
  • $a->email = "admin@example.com";
  • 親の login()AdminUser に書かなくても呼べる

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

演習問題(1問)

  1. ドリル 01 — User を継承した AdminUser

    README.md starter.php answer.php

サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。

完了にすると進捗に反映されます