Абстрактные классы
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 25 из 91.
abstract class — это class, экземпляр которого нельзя создать напрямую. Он служит шаблоном для других class, определяя method, которые дочерние class должны Implement. Вы создаёте abstract class с помощью ключевого слова abstract.
<?php
abstract class Shape {
protected $color;
public function __construct($color) {
$this->color = $color;
}
abstract public function calculateArea();
public function getColor() {
return $this->color;
}
}
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($color, $width, $height) {
parent::__construct($color);
$this->width = $width;
$this->height = $height;
}
public function calculateArea() {
return $this->width * $this->height;
}
}
$rect = new Rectangle("blue", 5, 3);
echo $rect->calculateArea();
Вывод:
15class Shape объявляет abstract method calculateArea(), не предоставляя его реализацию. Любой class, использующий Shape через extends, должен implement этот method. Обрати внимание, что abstract class также могут содержать обычные method, такие как getColor(), которые дочерние class наследуют напрямую.
abstract методы определяют, что должен делать дочерний class, но не то, как именно. Это гарантирует, что все фигуры имеют метод calculateArea(), позволяя каждой фигуре вычислять свою площадь по-разному.
Ключевой момент: Абстрактные классы объединяют структуру наследования с обязательными требованиями. Используй их, когда хочешь совместно использовать код связанными классами, обеспечивая при этом реализацию определённых методов каждым дочерним классом.
Задание
ЛегкоДавайте создадим систему медиаплеера, демонстрирующую, как abstract классы обеспечивают контракт, позволяя разным типам медиа реализовывать собственное поведение воспроизведения.
Вы организуете код в трёх файлах:
Media.php: Define abstractMediaclass, который служит шаблоном для всех типов медиа. В нём должны быть protected$titleproperty и constructor, который accepts и sets заголовок. Добавьте abstract method с именемplay(), который дочерние классы должны Implement. Также добавьте обычный methodgetTitle(), который returns заголовок. Этот concrete method будет унаследован всеми дочерними классами.Song.php: DefineSongclass, который extendsMedia. Подключите файл Media в начале. Этот class добавляет$artistproperty. Constructor должен accepts title и artist: используйтеparent::__construct()для title, затем самостоятельно установите artist. Implement требуемыйplay()method, чтобы он returns"Playing song: [title] by [artist]".Podcast.php: DefinePodcastclass, который extendsMedia. Подключите файл Media в начале. Этот class добавляет$episodeproperty (integer). Constructor должен accepts title и episode number: используйтеparent::__construct()для title, затем установите episode. Implement требуемыйplay()method, чтобы он returns"Playing podcast: [title] - Episode [episode]".
В main.php подключите оба файла Song и Podcast. Вы получите четыре входных значения: название песни, имя исполнителя, название подкаста и номер эпизода (в виде строки, которую нужно преобразовать в integer). Создайте Song и Podcast object с этими значениями. Сначала Print result вызова play() для песни, затем для подкаста — каждый результат на отдельной строке.
Этот challenge показывает, как abstract классы определяют контракт: каждый тип медиа должен иметь method play(), но каждый тип Implement его по-разному. Abstract Media class нельзя создать напрямую; он существует только для предоставления структуры и общей функциональности своим дочерним классам.
Попробуйте сами
<?php
require_once 'Song.php';
require_once 'Podcast.php';
// Читать входные данные
$songTitle = trim(fgets(STDIN));
$artistName = trim(fgets(STDIN));
$podcastTitle = trim(fgets(STDIN));
$episodeNumber = intval(trim(fgets(STDIN)));
// TODO: Создать объект Song с songTitle и artistName
// TODO: Создать объект Podcast с podcastTitle и episodeNumber
// TODO: Вывести результат вызова play() для song
// TODO: Вывести результат вызова play() для podcast
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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