ch02 8章中 2章目

ch02 — メソッドのオーバーライド

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch02 — メソッドのオーバーライド」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch02 — メソッドのオーバーライド」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch02 — メソッドのオーバーライド」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

オーバーライドとは

オーバーライドは 親クラスのメソッドを子クラスで同名再定義し、動作を差し替える 仕組みだ。

Notifier::send() がデフォルトで "通知を送信しました" を出すとする。EmailNotifier extends Notifiersend() を再定義しておけば、$mail->send()"メールで通知を送信しました" を出すようになる。継承だけだと親と同じ動きしかできないが、オーバーライドで「同じ呼び方で違う動き」を作れる。

書き方

親と同じ名前・同じ引数構造のメソッドを子クラスに書くだけ

class Notifier {
    public function send() {
        echo "通知を送信しました\n";
    }
}
class EmailNotifier extends Notifier {
    public function send() {
        echo "メールで通知を送信しました\n";  // 上書き
    }
}

PHP はインスタンスのクラスを見て、子に同名メソッドがあれば子を優先する (動的ディスパッチ)。

同じ呼び方で違う動き

$notifiers = [new EmailNotifier(), new SlackNotifier()];foreach で回して全部 send() を呼べる。ポリモーフィズム (多態) と呼ぶ書き方だ。

実務でもメール / Slack / SMS / Push のような複数チャネルを 同じ I/F で扱いたい場面で頻出する。呼ぶ側はチャネルの違いを気にしなくていい。

シグネチャの制約

子の引数の型・数と戻り値の型は 親と互換性を持つ必要 がある。PHP 7.4 以降は戻り値の 共変 (covariance) が許され、親の戻り値型を子で絞れる。

逆 (広げる) や引数を厳しく絞るのは互換性違反になる。まずは「同じシグネチャで上書きする」基本パターンに集中する。実メール送信は Symfony Mailer 等のライブラリを使うが、ここでは echo で代用する。

学習目標

  • 親と同名のメソッドを子で再定義できる
  • 子のインスタンスでは子のメソッドが呼ばれる
  • 同じ呼び方で通知チャネルごとに違う動きをさせられる

ドリル

no 内容
01 Notifier を継承した EmailNotifiersend() をオーバーライド

解説スライド 全 7 枚

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

  1. メソッドのオーバーライド

    Lesson 9 / Chapter 2

  2. ゴール

    通知システムを題材に、

    • 親クラス Notifier に共通の send() を持たせる
    • 子クラス EmailNotifier / SlackNotifiersend()チャネル別に差し替え られる
    • 同じ呼び方 $n->send($msg)クラスごとに違う送信先 に届く

    ここまでをコードで体験する。

  3. 継承だけだと、親と全く同じ動きになる

    <?php
    class Notifier {
        public function send(string $message) {
            echo "通知: {$message}\n";
        }
    }
    
    class EmailNotifier extends Notifier {
    }
    
    $n = new EmailNotifier();
    $n->send("登録完了しました");   // 「通知: 登録完了しました」 が出る
    • でも Email なら メール本文 として、Slack なら チャンネル投稿 として送りたい
    • 子クラスごとに送信処理を変えたい
  4. 子クラスで同じ名前のメソッドを書く

    <?php
    class Notifier {
        public function send(string $message) {
            echo "通知: {$message}\n";
        }
    }
    
    class EmailNotifier extends Notifier {
        public function send(string $message) {
            echo "[Email] 件名/本文として送信: {$message}\n";
        }
    }
    • 子クラスで親と 同じシグネチャ のメソッドを定義
    • これを オーバーライド と呼ぶ
  5. 子のインスタンスでは子のメソッドが呼ばれる

    <?php
    $n = new EmailNotifier();
    $n->send("登録完了しました");

    実行結果:

    [Email] 件名/本文として送信: 登録完了しました
    • EmailNotifier には send() が定義されているので、親 Notifier::send() は使われない
    • 親のメソッドは 上書き された状態になる
  6. 同じ呼び方で、クラスごとに違う動き

    <?php
    class SlackNotifier extends Notifier {
        public function send(string $message) {
            echo "[Slack] チャンネルに投稿: {$message}\n";
        }
    }
    
    class EmailNotifier extends Notifier {
        public function send(string $message) {
            echo "[Email] 件名/本文として送信: {$message}\n";
        }
    }
    
    $notifiers = [new EmailNotifier(), new SlackNotifier()];
    foreach ($notifiers as $n) {
        $n->send("登録完了しました");
    }
    • 全部 send() で呼べる
    • 実行されるのは そのインスタンスのクラスのメソッド

    本番では SMTP ライブラリや Slack の Webhook URL を使うが、ここでは echo で雰囲気だけ掴めば OK。

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

    ✅ 親と同名のメソッドを子で再定義できる ✅ 子のインスタンスでは子のメソッドが呼ばれる ✅ 同じ呼び方でクラスごとに違う動きをさせられる

    → ドリルへ

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

Lesson 9 / Chapter 2


ゴール

通知システムを題材に、

  • 親クラス Notifier に共通の send() を持たせる
  • 子クラス EmailNotifier / SlackNotifiersend()チャネル別に差し替え られる
  • 同じ呼び方 $n->send($msg)クラスごとに違う送信先 に届く

ここまでをコードで体験する。


継承だけだと、親と全く同じ動きになる

<?php
class Notifier {
    public function send(string $message) {
        echo "通知: {$message}\n";
    }
}

class EmailNotifier extends Notifier {
}

$n = new EmailNotifier();
$n->send("登録完了しました");   // 「通知: 登録完了しました」 が出る
  • でも Email なら メール本文 として、Slack なら チャンネル投稿 として送りたい
  • 子クラスごとに送信処理を変えたい

子クラスで同じ名前のメソッドを書く

<?php
class Notifier {
    public function send(string $message) {
        echo "通知: {$message}\n";
    }
}

class EmailNotifier extends Notifier {
    public function send(string $message) {
        echo "[Email] 件名/本文として送信: {$message}\n";
    }
}
  • 子クラスで親と 同じシグネチャ のメソッドを定義
  • これを オーバーライド と呼ぶ

子のインスタンスでは子のメソッドが呼ばれる

<?php
$n = new EmailNotifier();
$n->send("登録完了しました");

実行結果:

[Email] 件名/本文として送信: 登録完了しました
  • EmailNotifier には send() が定義されているので、親 Notifier::send() は使われない
  • 親のメソッドは 上書き された状態になる

同じ呼び方で、クラスごとに違う動き

<?php
class SlackNotifier extends Notifier {
    public function send(string $message) {
        echo "[Slack] チャンネルに投稿: {$message}\n";
    }
}

class EmailNotifier extends Notifier {
    public function send(string $message) {
        echo "[Email] 件名/本文として送信: {$message}\n";
    }
}

$notifiers = [new EmailNotifier(), new SlackNotifier()];
foreach ($notifiers as $n) {
    $n->send("登録完了しました");
}
  • 全部 send() で呼べる
  • 実行されるのは そのインスタンスのクラスのメソッド

本番では SMTP ライブラリや Slack の Webhook URL を使うが、ここでは echo で雰囲気だけ掴めば OK。


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

✅ 親と同名のメソッドを子で再定義できる ✅ 子のインスタンスでは子のメソッドが呼ばれる ✅ 同じ呼び方でクラスごとに違う動きをさせられる

→ ドリルへ

この章で取り組む 演習問題の流れ (1ステップ)
  1. 01 ドリル 01 — EmailNotifier で send() をオーバーライド README.md starter.php answer.php

演習問題の詳細

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

ドリル 01 — EmailNotifier で send() をオーバーライド

やること

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

  • メソッド send()"通知を送信しました" を 1 行出力する

Notifier を継承した EmailNotifier クラスを定義してください。

  • send() をオーバーライドして "メールで通知を送信しました" を 1 行出力する

EmailNotifier のインスタンスを作って send() を呼んでください。

期待される出力

メールで通知を送信しました

ヒント

  • 親と 同じ名前のメソッド を子に書けばオーバーライド
  • 子のインスタンスでは、自動的に子のメソッドが呼ばれる
  • 本物のメール送信は Symfony Mailer 等のライブラリを使うが、ここでは echo でチャネルの差し替えを再現する

🧪 ブラウザで試す

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

PHP ランタイム未読込

          

        

演習問題(1問)

  1. ドリル 01 — EmailNotifier で send() をオーバーライド

    README.md starter.php answer.php

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

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