Абстрактный класс и интерфейс

Оба задают контракт, но отвечают на разные задачи.

ВозможностьИнтерфейсАбстрактный класс
множественная реализация/наследованиедатолько один 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, Зачем нужны конструкторы абстрактным классам.