採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

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

テクノロジ系 / class-advanced (継承 / オーバーライド / abstract / interface / static / const / final)

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

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。

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

✅ 親と同名のメソッドを子で再定義できる

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

✅ 同じ呼び方でクラスごとに違う動きをさせられる

→ ドリルへ

考えてみよう

既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。

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

やること

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

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

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

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

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

期待される出力

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

ヒント

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

採点

php scripts/grade.php topics/class-advanced/ch02-override/drill/01-override-method/