Повторение переопределения методов
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 33 из 91.
Вы уже изучили переопределение method в главе «Наследование». Теперь давайте рассмотрим, как оно связано с полиморфизмом — одной из самых мощных концепций объектно-ориентированного программирования.
Полиморфизм означает «много форм». Когда вы переопределяете method в дочернем class, вы придаёте этому method другую форму, сохраняя то же имя. Магия происходит, когда вы работаете с объектами через их parent тип:
<?php
class Animal {
public function speak() {
return "Some sound";
}
}
class Dog extends Animal {
public function speak() {
return "Woof!";
}
}
class Cat extends Animal {
public function speak() {
return "Meow!";
}
}
function makeAnimalSpeak(Animal $animal) {
return $animal->speak();
}
echo makeAnimalSpeak(new Dog()) . "\n";
echo makeAnimalSpeak(new Cat());
Вывод:
Woof!
Meow!Функция makeAnimalSpeak() принимает любой Animal. Ей не известно и не важно, получает ли она Dog или Cat. PHP автоматически вызывает правильный переопределённый метод на основе фактического типа объекта во время выполнения.
Это полиморфизм в действии.
Этот подход позволяет писать гибкий код, работающий с семейством связанных объектов, не зная их конкретных типов. Позже можно добавлять новые классы animal, и function будет автоматически работать с ними.
Ключевой момент: Переопределение method обеспечивает полиморфизм, позволяя разным классам по-разному реагировать на один и тот же вызов method; фактический тип объекта определяется во время выполнения.
Задание
ЛегкоДавайте создадим систему музыкальных инструментов, демонстрирующую полиморфизм через переопределение method. Вы создадите базовый Instrument class и два дочерних class, каждый из которых будет воспроизводить собственный уникальный звук, а затем использовать одну function для полиморфного воспроизведения любого инструмента.
Вы распределите свой код по четырём файлам:
Instrument.php: CreateInstrumentclass с защищённым свойством$name, задаваемым через constructor. Addplay()method, который возвращает"[name] makes a sound". Это базовое поведение, которое дочерние class будут Override.Guitar.php: CreateGuitarclass, который extendsInstrument. Include parent file. Constructor accepts имя и передаёт его в parent constructor. Overrideplay()method, чтобы он возвращал"[name] strums a chord".Drum.php: CreateDrumclass, который extendsInstrument. Include parent file. Constructor accepts имя и передаёт его в parent constructor. Overrideplay()method, чтобы он возвращал"[name] beats a rhythm".main.php: Include оба файла — Guitar и Drum. Create function с именемperformWith, которая acceptsInstrumentparameter с указанием типа и возвращает результат вызоваplay()для него. Эта function демонстрирует полиморфизм. Она работает с любым типом инструмента благодаря указанию типа parent class.
Вы получите два входных значения: имя гитары и имя барабана. Create Guitar и Drum с этими именами. Передайте каждый из них в свою function performWith() и выведите результаты: сначала гитары, затем барабана, каждый результат — в отдельной строке.
Обратите внимание: performWith() accepts любой Instrument, однако PHP автоматически вызывает правильный переопределённый method play() в зависимости от фактического типа объекта во время выполнения. Это полиморфизм в действии!
Попробуйте сами
<?php
// Подключить файлы инструментов
require_once 'Guitar.php';
require_once 'Drum.php';
// Прочитать ввод
$guitarName = trim(fgets(STDIN));
$drumName = trim(fgets(STDIN));
// TODO: Создайте функцию под названием performWith, которая:
// - Принимает параметр Instrument (используйте type hint: Instrument $instrument)
// - Возвращает результат вызова play() у инструмента
// TODO: Создайте Guitar с $guitarName и Drum с $drumName
// TODO: Передайте каждый в performWith() и выведите результаты (сначала guitar, затем drum)
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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