Что такое полиморфизм в ООП?

«Что такое полиморфизм в ООП?» — вопрос из категории ООП, который задают на 38% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

В PHP полиморфизм реализуется преимущественно через:

1. Переопределение методов при наследовании

Дочерний класс предоставляет свою конкретную реализацию метода, уже объявленного в родительском классе.

abstract class NotificationSender {
    abstract public function send(string $message): void;
}

class EmailSender extends NotificationSender {
    public function send(string $message): void {
        echo "Отправляем email с текстом: {$message}n";
    }
}

class SmsSender extends NotificationSender {
    public function send(string $message): void {
        echo "Отправляем SMS: {$message}n";
    }
}

// Полиморфный вызов
function notifyUser(NotificationSender $sender, string $alert) {
    $sender->send($alert); // Неважно, какой именно sender пришёл. Он знает, КАК отправлять.
}

$email = new EmailSender();
$sms = new SmsSender();

notifyUser($email, "Ваш заказ готов!"); // Отправляем email...
notifyUser($sms, "Код подтверждения: 1234"); // Отправляем SMS...

2. Использование интерфейсов

Интерфейс определяет контракт (набор методов), который должны реализовать все классы, его использующие. Это чистейшая форма полиморфизма.

interface LoggerInterface {
    public function log(string $level, string $message): void;
}

class FileLogger implements LoggerInterface {
    public function log(string $level, string $message): void {
        file_put_contents('app.log', "[$level] $messagen", FILE_APPEND);
    }
}

class DatabaseLogger implements LoggerInterface {
    public function log(string $level, string $message): void {
        // Вставка записи $level, $message в таблицу логов
        echo "[DB LOG] [$level] $messagen";
    }
}

class Application {
    private LoggerInterface $logger;

    public function __construct(LoggerInterface $logger) {
        $this->logger = $logger; // Принимаем ЛЮБОЙ логгер, реализующий интерфейс
    }

    public function run() {
        $this->logger->log('INFO', 'Приложение запущено');
        // ... бизнес-логика
        $this->logger->log('ERROR', 'Что-то пошло не так');
    }
}

// Запуск с разными логгерами
$appWithFileLog = new Application(new FileLogger());
$appWithDbLog = new Application(new DatabaseLogger());

$appWithFileLog->run(); // Пишет в файл
$appWithDbLog->run();   // Пишет в базу данных

Суть полиморфизма: программа оперирует абстракциями (NotificationSender, LoggerInterface), а конкретное поведение определяется во время выполнения (runtime) типом реального объекта (EmailSender, DatabaseLogger). Это делает систему гибкой, расширяемой и легко тестируемой (зависимости можно подменять).

Видео-ответы