Переопределение методов
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 23 из 91.
Иногда унаследованный метод из родительского класса не совсем подходит тому, что нужно дочернему классу. Переопределение метода позволяет дочернему классу предоставить собственную реализацию метода, который уже существует в parent.
Чтобы переопределить method, просто определите method в дочернем class с тем же именем, что и у method parent:
<?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 completely заменяет parent’s speak() method своей версией. Когда вы вызываете speak() у объекта cat, PHP использует реализацию дочернего класса.
Вы также можете расширить поведение parent, объединив 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 или использовать parent::, чтобы расширить исходную реализацию.
Задание
ЛегкоДавайте создадим систему уведомлений, демонстрирующую, как дочерние class могут полностью заменять или расширять методы родительского class с помощью переопределения method.
Вы создадите три файла, которые будут работать вместе для отправки разных типов уведомлений, каждый со своим уникальным behavior:
Notification.php: Определите classNotification, который служит базовым для всех типов уведомлений. У него должно быть свойство$recipientс модификатором public и constructor, который принимает и устанавливает получателя. Включите methodsend($message), который возвращает"Sending to [recipient]: [message]".UrgentNotification.php: Определите classUrgentNotification, который extendsNotification. В верхней части подключите файл Notification. Этот class должен полностью переопределить methodsend($message), чтобы он возвращал"URGENT to [recipient]: [message]!!!": обратите внимание на префикс "URGENT" и восклицательные знаки в конце. Это демонстрирует полную замену behavior parent.LoggedNotification.php: Определите classLoggedNotification, который extendsNotification. В верхней части подключите файл Notification. Этот class должен переопределитьsend($message), но использовать реализацию parent: вызовитеparent::send($message)и добавьте" [logged]"к result. Это демонстрирует расширение, а не замену behavior.
В main.php подключите все три файла class уведомлений. Вы получите два входных значения: имя получателя и отправляемое сообщение. Создайте по одному instance каждого типа уведомлений (все используют одного и того же получателя), затем вызовите send() с сообщением для каждого из них. Выведите каждый result в отдельной строке в следующем order: обычное уведомление, срочное уведомление, затем уведомление с logged.
Этот challenge демонстрирует оба подхода к переопределению method: UrgentNotification полностью заменяет логику parent собственным форматированием, тогда как LoggedNotification использует parent::, чтобы сохранить исходный behavior и дополнить его.
Попробуйте сами
<?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. Логируемое уведомление
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Повторение — простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыПовторение — иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateМодификаторы доступа подробноГеттеры и сеттерыСокрытие информацииПродвижение конструктора (8.0)Повторение — система учёта студентов2Пространства имён и автозагрузка
Введение в пространства имёнКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerПовторение — структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс и абстрактный классАннотация типов с интерфейсамиПовторение — калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeПовторение — пользовательская коллекция3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищённые свойстваСвойства только для чтения (PHP 8.1)Повторение — менеджер банковского счёта6Полиморфизм
Повторение переопределения методовПолиморфизм через интерфейсыАннотации типов и объединённые типыПозднее статическое связываниеПовторение — обработчик платежей9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования, часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн StrategyПотренируйтесь самостоятельно: Онлайн-компилятор PHP