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

Чем отличается абстрактный класс от интерфейса

Абстрактный класс и интерфейс — это два способа определить контракт для классов в PHP, но они имеют разные цели и ограничения. Абстрактный класс может содержать реализацию методов и свойства, а интерфейс — только сигнатуры методов (без реализации) и не может содержать свойства. Класс может наследовать только один абстрактный класс, но может реализовывать множество интерфейсов.

Основные различия

КритерийАбстрактный классИнтерфейс
Ключевое словоabstract classinterface
СвойстваМожет иметь свойства (включая константы)Не может иметь свойства (только константы)
МетодыМожет содержать как абстрактные (без тела), так и обычные методы с реализациейВсе методы должны быть абстрактными (без тела)
НаследованиеКласс может наследовать только один абстрактный классКласс может реализовывать несколько интерфейсов
Модификаторы доступаМетоды могут быть public, protected, privateВсе методы должны быть public

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

Абстрактный класс объявляется с ключевым словом abstract. Он может содержать абстрактные методы (без тела) и обычные методы с реализацией. Абстрактные методы обязаны быть реализованы в дочерних классах. Например:

php
abstract class Car {
    protected string $brand;

    abstract public function startEngine(): void;

    public function getBrand(): string {
        return $this->brand;
    }
}

Интерфейс объявляется с ключевым словом interface. Он определяет только сигнатуры методов, которые должны быть реализованы в классе. Интерфейс не может содержать свойства, но может содержать константы. Например:

php
interface Drivable {
    public function drive(): void;
    public function stop(): void;
}

Класс может реализовать несколько интерфейсов, перечисляя их через запятую:

php
class Bicycle implements Drivable, EcoFriendly {
    public function drive(): void {
        // реализация
    }

    public function stop(): void {
        // реализация
    }
}

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

Абстрактный класс подходит, когда у группы классов есть общая реализация (например, общие свойства или методы), которую можно вынести в базовый класс. Он также позволяет задать общий шаблон для иерархии классов. Например, абстрактный класс Car может содержать общую логику для всех автомобилей, а конкретные классы Ford и Toyota наследуют её и добавляют свои особенности.

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

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

  • Нельзя создать экземпляр ни абстрактного класса, ни интерфейса.
  • Если класс наследует абстрактный класс, он должен реализовать все абстрактные методы, иначе класс тоже должен быть объявлен абстрактным.
  • Если класс реализует интерфейс, он должен реализовать все методы интерфейса, иначе класс должен быть объявлен абстрактным.
  • В PHP интерфейсы могут наследовать другие интерфейсы, но не классы.
  • Абстрактные классы могут реализовывать интерфейсы, но это не обязательно.

Коротко

  • Абстрактный класс — это частично реализованный класс: может иметь свойства и методы с телом.
  • Интерфейс — это чистый контракт: только сигнатуры методов, без свойств и реализации.
  • Класс наследует один абстрактный класс, но реализует много интерфейсов.
  • Выбирайте абстрактный класс для общей логики, интерфейс — для общего поведения.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы