Переопределение методов
Часть раздела Объектно-ориентированное программирование путешествия по 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::, чтобы дополнить оригинальную реализацию.
Задание
ЛегкоДавайте создадим систему уведомлений, которая демонстрирует, как дочерние классы могут полностью заменять или расширять методы родительских классов с помощью переопределения методов.
Вы создадите три файла, которые работают вместе для отправки различных типов уведомлений, каждый из которых обладает своим уникальным поведением:
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. Логируемое уведомление
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Итоги — Простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыИтоги — Иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateПодробный разбор модификаторов доступаГеттеры и сеттерыСокрытие данныхConstructor Promotion (8.0)Итоги — Система учета студентов10Продвинутые концепции ООП
Композиция против наследованияВнедрение зависимостейАнонимные классыПеречисления (PHP 8.1)Файберы (PHP 8.1)Глубокое погружение в клонирование объектовГенераторы и итераторы13Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий2Пространства имен и автозагрузка
Введение в пространства именКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerИтоги: структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс против абстрактного классаType Hinting с интерфейсамиИтоги — Калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeИтоги — Кастомная коллекция11Система типов и обработка ошибок
Объявление типовNullable-типыТипы объединения и пересеченияКлассы исключенийИерархия пользовательских исключенийTry, Catch, FinallyИтоги — Валидатор форм14Проект: Управление библиотекой
Обзор проектаКлассы Book и User3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищенные свойстваСвойства Readonly (PHP 8.1)Итоги — Менеджер банковского счета6Полиморфизм
Снова о переопределении методовПолиморфизм через интерфейсыType Hinting и Union TypesПозднее статическое связываниеИтоги — Payment Processor9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн StrategyПотренируйтесь самостоятельно: Онлайн-компилятор PHP