Что такое абстрактный класс в объектно-ориентированном программировании?

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

Ответ

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

Основные цели:

  1. Выделение общего кода: Предотвращение дублирования в наследниках.
  2. Определение контракта: Объявление абстрактных методов, которые наследники обязаны реализовать.
  3. Ограничение создания объектов: Класс представляет абстрактную сущность (например, Shape, Animal), объект которой не имеет смысла.

Характеристики (на примере Java):

// 1. Объявление абстрактного класса
abstract class DataProcessor {
    // 2. Поле (состояние) - может быть
    protected String inputSource;

    // 3. Конструктор - может быть
    public DataProcessor(String source) {
        this.inputSource = source;
    }

    // 4. Абстрактный метод (контракт) - БЕЗ реализации
    public abstract void processData();

    // 5. Конкретный (реализованный) метод - общая логика
    public void validate() {
        System.out.println("Validating data from " + inputSource);
    }
}

// 6. Конкретный класс-наследник
class FileProcessor extends DataProcessor {
    public FileProcessor(String path) {
        super(path); // Вызов конструктора родителя
    }

    // 7. ОБЯЗАТЕЛЬНАЯ реализация абстрактного метода
    @Override
    public void processData() {
        validate(); // Можно использовать общий метод
        System.out.println("Reading and processing file: " + inputSource);
    }
}

// Использование:
// DataProcessor p = new DataProcessor(); // ОШИБКА: нельзя создать
DataProcessor p = new FileProcessor("data.txt"); // OK: полиморфизм
p.processData();
Сравнение с интерфейсом (Java 8+): Критерий Абстрактный класс Интерфейс
Состояние Может иметь поля экземпляра Только static final константы (по умолчанию)
Конструктор Есть Нет
Множественное наследование Нет (только один родительский класс) Да (много интерфейсов)
Методы по умолчанию Полные реализации default-методы (с Java 8)
Когда использовать Для тесно связанных классов с общим состоянием/поведением Для определения контракта (возможностей) для слабосвязанных сущностей

"Почему" и практика: Абстрактный класс используют, когда есть четкая иерархия "is-a" (является) и общая базовая логика. Например, PaymentProcessor с абстрактным методом authorize() и общими методами logTransaction(), formatCurrency().