Встречается на 60% собеседований по PHP

В чём суть абстрактного класса

Абстрактный класс — это класс, который нельзя инстанциировать напрямую; он служит шаблоном для других классов, определяя общий интерфейс и частичную реализацию. В PHP абстрактный класс объявляется с ключевым словом abstract и может содержать как обычные методы с реализацией, так и абстрактные методы без тела, которые обязаны реализовать наследники.

Как это работает

Абстрактный класс предназначен для моделирования общих характеристик группы связанных объектов. Он позволяет:

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

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

Пример

Рассмотрим пример на PHP: абстрактный класс ТранспортноеСредство определяет общее свойство скорость и метод установитьСкорость(), а также требует от наследников реализовать метод двигаться().

php
abstract class ТранспортноеСредство {
    protected $скорость;

    public function установитьСкорость($скорость) {
        $this->скорость = $скорость;
    }

    // Абстрактный метод: наследник обязан реализовать
    abstract public function двигаться();
}

class Автомобиль extends ТранспортноеСредство {
    public function двигаться() {
        echo "Движется на скорости: " . $this->скорость . " км/ч";
    }
}

// $транспорт = new ТранспортноеСредство(); // Ошибка: нельзя создать экземпляр абстрактного класса
$автомобиль = new Автомобиль();
$автомобиль->установитьСкорость(60);
$автомобиль->двигаться(); // Выведет: Движется на скорости: 60 км/ч

Здесь ТранспортноеСредство задаёт общий каркас: любое транспортное средство имеет скорость и умеет её устанавливать, но способ движения у каждого свой. Попытка создать объект абстрактного класса приведёт к фатальной ошибке.

Подводные камни

  • Нельзя инстанциировать: попытка new АбстрактныйКласс() вызовет ошибку. Это важно для проектирования: абстрактный класс существует только как основа для наследования.
  • Обязательная реализация абстрактных методов: если наследник не реализует все абстрактные методы, он сам должен быть объявлен абстрактным, иначе возникнет ошибка.
  • Ограничение одиночного наследования: в PHP класс может наследовать только один абстрактный класс, в отличие от интерфейсов, которых можно реализовать несколько. Это ограничение нужно учитывать при проектировании иерархии.
  • Абстрактные методы не могут быть private: они должны быть protected или public, чтобы наследники могли их реализовать.

Когда использовать

Абстрактный класс уместен, когда несколько классов имеют общую логику и состояние, но отличаются в некоторых ключевых аспектах. Например, базовый класс для различных видов животных, где общий метод есть() реализован, а издаватьЗвук() — абстрактный. Если же требуется только контракт без реализации, лучше выбрать интерфейс.

Коротко

  • Абстрактный класс — это класс, который нельзя создать через new; он служит шаблоном для наследников.
  • Он может содержать реализацию общих методов и абстрактные методы, которые наследники обязаны реализовать.
  • Используется для уменьшения дублирования кода и гарантии единого интерфейса в группе связанных классов.
  • Помните об ограничении одиночного наследования и о том, что абстрактные методы не могут быть private.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы