Menu
Coddy logo textTech

Анонимные классы

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 58 из 91.

Иногда вам нужен простой, разовый объект без лишних затрат на определение полноценного класса. Анонимные классы позволяют создавать объекты «на лету», именно там, где они вам нужны. Они особенно полезны в сочетании с внедрением зависимостей.

Анонимный класс определяется с помощью 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 message

Анонимные классы также могут расширять другие классы, использовать трейты и принимать аргументы конструктора. Они имеют полный доступ к возможностям ООП — они просто определяются по месту (inline), а не в отдельном файле. Используйте их, когда полное определение класса было бы избыточным, но вам все равно требуется объектно-ориентированное поведение.

challenge icon

Задание

Легко

Давайте создадим систему форматирования данных, которая демонстрирует мощь анонимных классов. Вместо создания отдельных файлов классов для простых одноразовых реализаций, вы будете использовать анонимные классы для создания быстрых реализаций прямо там, где они вам нужны.

Вы организуете свой код в двух файлах:

  • FormatterInterface.php — Определите интерфейс с именем FormatterInterface с единственным методом format(string $data): string. Это устанавливает контракт, которому должен следовать любой форматер.
  • main.php — Подключите файл интерфейса и создайте класс DataProcessor, который использует внедрение зависимостей для принятия любого форматера. Класс должен:
    • Принимать FormatterInterface в своем конструкторе
    • Иметь метод process(string $data), который делегирует работу внедренному форматеру и возвращает его результат

    Вы получите два входных значения: тип формата ("upper" или "reverse") и строку для форматирования.

    В зависимости от типа формата создайте анонимный класс, реализующий FormatterInterface:

    • Для "upper": метод format() должен возвращать данные, преобразованные в верхний регистр
    • Для "reverse": метод format() должен возвращать перевернутые данные

    Внедрите ваш анонимный класс в DataProcessor, вызовите process() с входной строкой и выведите результат.

Этот подход идеально подходит, когда вам нужна быстрая реализация без загромождения кодовой базы файлами классов одноразового использования. Анонимный класс создается по месту (inline), реализует требуемый интерфейс и может быть передан куда угодно, где ожидается этот интерфейс.

Шпаргалка

Анонимные классы позволяют создавать объекты «на лету» без определения полноценного класса. Они определяются с помощью new class, за которым следует тело класса:

<?php
$logger = new class {
    public function log(string $message): void {
        echo "Log: $message";
    }
};

$logger->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");

Анонимные классы поддерживают все возможности ООП: они могут расширять другие классы, использовать трейты и принимать аргументы конструктора. Используйте их, когда определение полноценного класса было бы избыточным, но вам все равно требуется объектно-ориентированное поведение.

Попробуйте сами

<?php
require_once 'FormatterInterface.php';

// TODO: Создайте класс DataProcessor, который:
// - Принимает FormatterInterface в своем конструкторе
// - Имеет метод process(string $data), который делегирует выполнение форматировщику

// Чтение входных данных
$formatType = trim(fgets(STDIN));
$inputString = trim(fgets(STDIN));

// TODO: На основе $formatType ("upper" или "reverse") создайте анонимный класс,
// который реализует FormatterInterface
// - Для "upper": format() должен возвращать версию данных в верхнем регистре
// - Для "reverse": format() должен возвращать перевернутую версию данных

// TODO: Создайте DataProcessor с вашим анонимным классом форматировщика
// Вызовите process() с входной строкой и выведите результат

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование