Какой принцип SOLID нарушается при использовании final-классов в Java?

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

Ответ

Класс, объявленный как final, напрямую нарушает принцип Open/Closed Principle (OCP) — "классы должны быть открыты для расширения, но закрыты для модификации".

Почему? Ключевое слово final запрещает наследование от класса, что блокирует самый прямой способ расширения его поведения.

Пример проблемы:

// Final-класс нельзя унаследовать
final class PaymentProcessor {
    public void process(double amount) {
        System.out.println("Processing payment: " + amount);
    }
}

// Попытка расширить функциональность через наследование НЕВОЗМОЖНА:
// class AdvancedPaymentProcessor extends PaymentProcessor { // Ошибка компиляции
//     public void processWithFee(double amount) { ... }
// }

Как следовать OCP с final-классами? Принцип OCP можно соблюсти, используя не наследование, а композицию и интерфейсы:

// 1. Выделяем интерфейс
interface Processor {
    void process(double amount);
}

// 2. Final-класс реализует интерфейс
final class BasicPaymentProcessor implements Processor {
    @Override
    public void process(double amount) { /* базовая логика */ }
}

// 3. Расширяем функциональность через композицию и новый класс
class AdvancedPaymentProcessor implements Processor {
    private final Processor delegate; // Композиция
    public AdvancedPaymentProcessor(Processor delegate) {
        this.delegate = delegate;
    }
    @Override
    public void process(double amount) {
        delegate.process(amount); // Делегирование
        addTransactionFee(amount); // Расширение
    }
    private void addTransactionFee(double amount) { /* ... */ }
}