Menu
Coddy logo textTech

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

CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 23/91。

継承した parent class の method が、child class に必要なものに完全には合わないことがあります。Method overriding を使うと、child class は parent にすでに存在する method に独自の実装を提供できます。

method を Override するには、parent の method と same 名前の method を子 class に定義するだけです。

<?php
class Animal {
    public $name;
    
    public function __construct($name) {
        $this->name = $name;
    }
    
    public function speak() {
        return "$this->name makes a sound";
    }
}

class Cat extends Animal {
    public function speak() {
        return "$this->name says meow";
    }
}

$cat = new Cat("Whiskers");
echo $cat->speak();

出力:

Whiskers says meow

Cat class は、parent の speak() method を completely own version に置き換えます。cat オブジェクトに対して speak() を呼び出すと、PHP は子クラスの実装を使用します。

parent:: と独自のロジックを組み合わせることで、親の動作を拡張することもできます。

<?php
class Dog extends Animal {
    public function speak() {
        return parent::speak() . " - woof woof!";
    }
}

$dog = new Dog("Rex");
echo $dog->speak();

出力:

Rex makes a sound - woof woof!

重要なポイント: methodのオーバーライドにより、子クラスは継承した behaviorをカスタマイズできます。methodをcompletely replaceすることも、parent::を使用して元の実装を基に構築することもできます。

challenge icon

チャレンジ

簡単

子クラスがメソッドのオーバーライドによって、親クラスのメソッドを完全に置き換えたり拡張したりできることを示す通知システムを構築しましょう。

それぞれ独自の behavior を持つ異なる種類の通知を送信する、連携して動作する3つのファイルを作成します。

  • Notification.php:すべての notification type の基盤となる Notification class を定義します。public な $recipient property と、recipient を受け取って設定する constructor を持たせます。send($message) method も含め、この method は "Sending to [recipient]: [message]" を returns します。
  • UrgentNotification.phpNotification を extends する UrgentNotification class を定義します。先頭で Notification file を include します。この class は send($message) method を完全に Override し、"URGENT to [recipient]: [message]!!!" を returns します。"URGENT" prefix と末尾の exclamation marks に注目してください。これは parent の behavior を完全に置き換える例です。
  • LoggedNotification.phpNotification を extends する LoggedNotification class を定義します。先頭で Notification file を include します。この class は send($message) を Override しますが、parent の implementation を基盤にします。parent::send($message) を Call し、result に " [logged]" を append します。これは behavior を置き換えるのではなく拡張する例です。

main.php では、3つすべての notification class files を include します。2つの input、つまり recipient name と送信する message を受け取ります。各 notification type の instance を1つずつ(すべて same recipient を使用して)Create し、それぞれに message を指定して send() を Call します。各 result をそれぞれ別の line に Print します。order は regular notification、urgent notification、logged notification です。

この challenge では、method overriding への2つのアプローチを示します。UrgentNotification は parent の logic を独自の formatting で completely replace し、一方 LoggedNotificationparent:: を使用して original behavior を維持し、それに追加します。

自分で試してみよう

<?php

require_once 'Notification.php';
require_once 'UrgentNotification.php';
require_once 'LoggedNotification.php';

// 入力を読み取る
$recipient = trim(fgets(STDIN));
$message = trim(fgets(STDIN));

// TODO: 各通知タイプのインスタンスを1つずつ作成する(すべて同じ受信者を使用)

// TODO: 各通知でメッセージを指定して send() を呼び出す
// 各結果を次の順序でそれぞれ1行ずつ出力する:
// 1. 通常の通知
// 2. 緊急通知
// 3. ログ付き通知

?>
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: PHPオンラインコンパイラ