Анонимные классы
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 58 из 91.
Иногда вам нужен простой однократный объект без затрат на определение полноценного класса. Anonymous classes позволяют создавать объекты на лету, прямо там, где они нужны. Они особенно полезны в сочетании с внедрением зависимостей.
Anonymous class определяется с помощью new class, за которым следует тело класса:
<?php
$logger = new class {
public function log(string $message): void {
echo "Log: $message";
}
};
$logger->log("Hello!");
Вывод:
Log: Hello!Анонимные классы становятся мощными при реализации интерфейсов. Это идеально подходит для тестирования или случаев, когда вам нужна быстрая реализация без загромождения кодовой базы одноразовыми классами:
<?php
interface Notifier {
public function send(string $message): string;
}
function notify(Notifier $notifier, string $msg): string {
return $notifier->send($msg);
}
$result = notify(new class implements Notifier {
public function send(string $message): string {
return "Sent: $message";
}
}, "Test message");
echo $result;
Вывод:
Sent: Test messageAnonymous class могут также расширять другие классы, использовать трейты и принимать аргументы constructor. Они имеют полный доступ к возможностям ООП — они просто определены инлайн, а не в отдельном файле. Используй их, когда полное определение class было бы избыточным, но тебе всё ещё требуется объектно-ориентированное поведение.
Задание
ЛегкоДавайте создадим систему форматирования data, демонстрирующую возможности anonymous class. Вместо создания отдельных файлов class для простых одноразовых реализаций вы будете использовать anonymous class, чтобы быстро создавать реализации прямо там, где они нужны.
Вы организуете код в двух файлах:
FormatterInterface.php: Define interface под названиемFormatterInterfaceс single methodformat(string $data): string. Это устанавливает контракт, которому должен следовать любой formatter.main.php: Подключите файл interface и создайте classDataProcessor, который использует внедрение зависимостей для принятия любого formatter. Class должен:- Принимать
FormatterInterfaceв своём constructor - Have method
process(string $data), который delegates вызов внедрённому formatter и возвращает его result
Вы получите два входных значения: тип format (
"upper"или"reverse") и string для форматирования.В зависимости от типа format создайте anonymous class, который implements
FormatterInterface:- Для
"upper": methodformat()должен возвращать data, преобразованные в uppercase - Для
"reverse": methodformat()должен возвращать data в reverse-порядке
Внедрите свой anonymous class в
DataProcessor, вызовитеprocess()с входной string и выведите result.- Принимать
Этот подход идеально подходит, когда вам нужна быстрая реализация без загромождения codebase файлами class, используемыми один раз. Anonymous class создаётся inline, implements требуемый interface и может быть передан в любое место, где ожидается этот interface.
Попробуйте сами
<?php
require_once 'FormatterInterface.php';
// TODO: Создайте класс DataProcessor, который:
// - Принимает FormatterInterface в своём конструкторе
// - Имеет метод process(string $data), который делегирует работу форматтеру
// Читаем ввод
$formatType = trim(fgets(STDIN));
$inputString = trim(fgets(STDIN));
// TODO: Based on $formatType ("upper" or "reverse"), create an anonymous class
// который реализует FormatterInterface
// - Для "upper": format() должен возвращать версию данных в верхнем регистре
// - Для "reverse": format() должен возвращать перевёрнутую версию данных
// TODO: Create a DataProcessor with your anonymous class formatter
// Вызовите process() со входной строкой и выведите результат
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Повторение — простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыПовторение — иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateМодификаторы доступа подробноГеттеры и сеттерыСокрытие информацииПродвижение конструктора (8.0)Повторение — система учёта студентов10Продвинутые концепции ООП
Композиция и наследованиеВнедрение зависимостейАнонимные классыПеречисления (PHP 8.1)Файберы (PHP 8.1)Глубокое погружение в клонирование объектовГенераторы и итераторы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