ENIGMA AI
ENIGMA AI

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

встречается 33× junior oop

Как ответить

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

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

abstract class Product {
    protected string $sku;
    protected float $price;

    public function updatePrice(float $newPrice): void {
        $this->price = $newPrice;
    }

    abstract public function calculateTax(): float;
}

Интерфейс нужен, когда мы хотим гарантировать наличие определенного поведения у классов, которые могут быть вообще не связаны друг с другом. Например, интерфейс Exportable может быть и у товара, и у пользователя, и у логов системы. Им не нужно общее состояние, им нужно просто уметь превращаться в JSON или XML.

interface Exportable {
    public function toFormat(): string;
}

class User implements Exportable {
    public function toFormat(): string { return "json_user_data"; }
}

class Order implements Exportable {
    public function toFormat(): string { return "json_order_data"; }
}

Основные критерии выбора:

  • Наследование состояния: Если нужны поля (свойства) и модификаторы доступа (protected, private), используйте абстрактный класс. В интерфейсах (в большинстве языков) нельзя хранить состояние объекта.
  • Множественная реализация: Если класс должен поддерживать несколько разных функций (например, логироваться, клонироваться и сериализоваться), это делается через интерфейсы.
  • Готовая логика: Если вы хотите дать наследникам не только сигнатуры методов, но и их базовую реализацию, чтобы избежать дублирования кода, подходит абстрактный класс.
  • Связанность системы: Интерфейсы создают более слабую связанность (loose coupling), что упрощает тестирование и замену компонентов.

В современной разработке чаще советуют отдавать предпочтение интерфейсам (принцип Composition over Inheritance), так как это делает архитектуру гибче. Абстрактные классы хороши на нижних уровнях системы для создания каркаса конкретного модуля.

Ключевые тезисы

  • Разница в наследовании: одиночное для классов и множественное для интерфейсов.
  • Наличие состояния: абстрактные классы могут иметь поля, интерфейсы — только методы (и константы).
  • Смысловая нагрузка: IS-A (является) для классов против CAN-DO (умеет) для интерфейсов.
  • Реализация: абстрактный класс позволяет задать поведение по умолчанию, интерфейс только описывает контракт.

Что спросят дальше

  • — Можно ли создать экземпляр абстрактного класса и почему?
  • — Что такое Default Methods в интерфейсах (например, в Java 8+) и как они меняют разницу с абстрактными классами?
  • — В каких случаях наследование может стать проблемой по сравнению с композицией?

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение