В чем разница между абстрактным классом и интерфейсом?

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

Ответ

Основное концептуальное различие в том, что абстрактный класс определяет что объект есть (is-a relationship), а интерфейс определяет что объект может делать (capability).

Абстрактный класс:

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

Интерфейс:

  • До Java 8 / C# 8.0 содержал только сигнатуры методов (контракт). Современные версии позволяют добавлять реализации по умолчанию (default в Java, virtual в C#) и статические методы.
  • Не может содержать поля состояния (только константы).
  • Не может иметь конструктор.
  • Класс может реализовывать множество интерфейсов.
  • Используется для определения контракта, который могут выполнять несвязанные классы.

Пример на C#:

// Абстрактный класс: общая базовая логика
abstract class DataExporter
{
    protected string _data;
    public DataExporter(string data) { _data = data; } // Конструктор
    public virtual void PrepareData() { /* общая реализация */ } // Конкретный метод
    public abstract void Export(); // Абстрактный метод
}

// Интерфейс: контракт на возможность логирования
interface ILoggable
{
    void Log(string message); // Только сигнатура
}

// Класс использует и наследование, и реализацию интерфейса
class CsvExporter : DataExporter, ILoggable
{
    public CsvExporter(string data) : base(data) { }
    public override void Export() { /* экспорт в CSV */ }
    public void Log(string message) { /* логирование */ }
}

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