Короткий ответ
Абстрактный класс — это класс, который нельзя инстанцировать: он задаёт шаблон наследникам и может содержать абстрактные методы, обычные методы с реализацией, поля, конструкторы и статические члены. Интерфейс описывает контракт поведения: до Java 8 в нём были только абстрактные методы и константы, с Java 8 появились default- и static-методы, с Java 9 — private-методы.
Как это работает подробнее
Оба механизма описывают абстракции, но решают разные задачи. Класс может наследовать только один абстрактный класс, зато реализует сколько угодно интерфейсов — это частично компенсирует отсутствие множественного наследования. На практике их часто комбинируют: класс наследует абстрактную базу и дополнительно реализует один или несколько интерфейсов.
- Состояние — абстрактный класс может иметь поля и конструкторы (вызываются через super()); в интерфейсе только константы public static final.
- Методы — в абстрактном классе абстрактные и обычные методы; в интерфейсе с Java 8 — default, static, а с Java 9 — private.
- Наследование — extends только один абстрактный класс, implements множество интерфейсов.
- Назначение — абстрактный класс объединяет родственные классы с общим кодом; интерфейс задаёт поведение для любых, даже не связанных между собой классов.
Пример кода
Circle.java
abstract class Shape { // абстрактный класс: состояние и код
protected String name;
abstract double area(); // абстрактный метод без тела
String describe() { // обычный метод с реализацией
return name;
}
}
interface Drawable { // интерфейс: контракт поведения
void draw(); // абстрактный метод
default void show() { } // default-метод (Java 8)
}
public class Circle extends Shape implements Drawable {
Circle(String name) { this.name = name; }
double area() {
return Math.PI * 10 * 10;
}
public void draw() {
System.out.println("draw");
}
}Что использовать на практике
- Выбирай абстрактный класс, когда наследники родственны и должны разделять состояние и общую реализацию.
- Выбирай интерфейс, когда важен только контракт поведения, а классы-реализаторы могут быть не связаны между собой.
- default-методы используй для обратной совместимости и общих поведенческих реализаций.
Подводные камни
- Множественного наследования классов в Java нет: extends допустим только к одному абстрактному классу.
- В интерфейсе нельзя объявить поля состояния и конструкторы — только константы и методы.
- При одинаковых default-методах в двух интерфейсах класс обязан явно переопределить конфликтующий метод.
Как отвечать на собеседовании
- Сформулируй суть: абстрактный класс задаёт шаблон с состоянием, интерфейс — контракт поведения → перечисли различия (поля, конструкторы, методы, число супертипов) → добавь историю Java 8 и 9 → приведи правило выбора → закончи примером комбинации extends и implements.