Абстрактный класс и интерфейс
Оба задают контракт, но отвечают на разные задачи.
| Возможность | Интерфейс | Абстрактный класс |
|---|---|---|
| множественная реализация/наследование | да | только один superclass |
| instance-состояние | нет | да |
| конструктор | нет | да |
| методы с реализацией | default, static, private | любые допустимые |
| поля | только неявно public static final | обычные поля |
| доступ к методам | public API и private helpers | все модификаторы |
interface Identified {
UUID id();
default String shortId() {
return id().toString().substring(0, 8);
}
}
abstract class AbstractTask {
private final UUID id;
protected AbstractTask(UUID id) {
this.id = Objects.requireNonNull(id);
}
public final UUID id() {
return id;
}
public abstract void execute();
}Интерфейс подходит роли/capability и границе между компонентами. Абстрактный класс — близкой семье типов с общей реализацией, защищёнными extension points и состоянием.
Современные нюансы
- default-метод не превращает интерфейс в класс: instance-состояния всё равно нет;
- конфликт одинаковых default-методов реализация обязана разрешить явно;
- методы
Objectнельзя «переопределить по умолчанию» обычным default-методом; - sealed interface может закрыть набор реализаций;
- изменение интерфейса новым abstract-методом ломает реализации, default-метод помогает совместимости, но должен иметь разумную общую семантику.
На собеседовании
Есть ли состояние у интерфейса? Только константы public static final, не состояние экземпляра.
Можно ли реализовать несколько интерфейсов? Да.
Когда нужен abstract class? Когда есть общий state/lifecycle или protected реализация для тесной иерархии.
Что при конфликте default-методов? Класс явно переопределяет метод и выбирает/сочетает реализации.
Связано: Абстрактные классы, Интерфейсы Java, Зачем нужны конструкторы абстрактным классам.