Что может содержать абстрактный класс в Java, но не может интерфейс (до Java 8)?

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

Ответ

До Java 8 различия были более явными. Сейчас интерфейсы могут содержать default и static методы, но следующие элементы по-прежнему уникальны для абстрактных классов:

  1. Конструкторы. Только классы (включая абстрактные) могут иметь конструкторы.
  2. Поля экземпляра (не-static) с любым модификатором доступа. В интерфейсах все поля неявно public static final.
  3. Методы с реализацией и модификаторами private или protected. В интерфейсах методы могут быть public, private (Java 9+) или default/static с реализацией, но не protected.
  4. Инициализация состояния объекта через поля и конструкторы.

Пример абстрактного класса:

abstract class Animal {
    // Поле экземпляра (нельзя в интерфейсе)
    private String name;
    protected int age;

    // Конструктор (нельзя в интерфейсе)
    public Animal(String name) {
        this.name = name;
    }

    // protected метод с реализацией (нельзя в интерфейсе)
    protected void eat() {
        System.out.println(name + " is eating.");
    }

    // Абстрактный метод (может быть и в интерфейсе)
    abstract void makeSound();
}

Ключевое отличие: Абстрактный класс описывает сущность и может хранить её состояние. Интерфейс описывает контракт или поведение.