Menu
Coddy logo textTech

Переопределение методов

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 23 из 91.

Иногда унаследованный метод родительского класса не совсем подходит для нужд дочернего класса. Переопределение методов (Method overriding) позволяет дочернему классу предоставить собственную реализацию метода, который уже существует в родительском классе.

Чтобы переопределить метод, просто определите метод в дочернем классе с тем же именем, что и метод родительского класса:

<?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 полностью заменяет родительский метод speak() своей собственной версией. Когда вы вызываете speak() у объекта cat, 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!

Ключевой момент: Переопределение методов позволяет дочерним классам настраивать унаследованное поведение. Вы можете полностью заменить метод или использовать parent::, чтобы дополнить оригинальную реализацию.

challenge icon

Задание

Легко

Давайте создадим систему уведомлений, которая демонстрирует, как дочерние классы могут полностью заменять или расширять методы родительских классов с помощью переопределения методов.

Вы создадите три файла, которые работают вместе для отправки различных типов уведомлений, каждый из которых обладает своим уникальным поведением:

  • Notification.php — Определите класс Notification, который служит базой для всех типов уведомлений. Он должен иметь публичное свойство $recipient и конструктор, который принимает и устанавливает получателя. Включите метод send($message), который возвращает "Sending to $this->recipient: $message".
  • UrgentNotification.php — Определите класс UrgentNotification, который расширяет Notification. Подключите файл Notification в начале. Этот класс должен полностью переопределить метод send($message), чтобы он возвращал "URGENT to $this->recipient: $message!!!" — обратите внимание на префикс "URGENT" и восклицательные знаки в конце. Это демонстрирует полную замену поведения родителя.
  • LoggedNotification.php — Определите класс LoggedNotification, который расширяет Notification. Подключите файл Notification в начале. Этот класс должен переопределить send($message), но основываться на реализации родителя: вызовите parent::send($message) и добавьте " [logged]" к результату. Это демонстрирует расширение, а не замену поведения.

В main.php подключите все три файла классов уведомлений. Вы получите два входных значения: имя получателя и сообщение для отправки. Создайте по одному экземпляру каждого типа уведомления (все используют одного и того же получателя), затем вызовите send() с сообщением для каждого из них. Выведите каждый результат на отдельной строке в следующем порядке: обычное уведомление, срочное уведомление, а затем логируемое уведомление.

Эта задача показывает оба подхода к переопределению методов — UrgentNotification полностью заменяет логику родителя своим собственным форматированием, в то время как LoggedNotification использует parent::, чтобы сохранить исходное поведение и дополнить его.

Попробуйте сами

<?php

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

// Чтение входных данных
$recipient = trim(fgets(STDIN));
$message = trim(fgets(STDIN));

// TODO: Создать по одному экземпляру каждого типа уведомления (все используют одного и того же получателя)

// TODO: Вызвать метод send() с сообщением для каждого уведомления
// Вывести каждый результат на отдельной строке в следующем порядке:
// 1. Обычное уведомление
// 2. Срочное уведомление
// 3. Логируемое уведомление

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор PHP