В чем разница между абстрактным класом и интерфейсом

Ответ

Основные различия:

  1. Наследование: Класс может наследовать только один абстрактный класс, но реализовывать множество интерфейсов.

  2. Реализация: Абстрактный класс может содержать реализованные методы, интерфейс - только сигнатуры (до Java 8). Сейчас интерфейсы могут иметь default и static методы.

  3. Состояние: Абстрактный класс может содержать поля, интерфейс - только константы (public static final).

Пример:

// Интерфейс
interface Drawable {
    void draw(); // абстрактный метод
    default void resize() { /* реализация */ }
}

// Абстрактный класс
abstract class Shape {
    protected int x, y; // поля

    abstract void area(); // абстрактный метод

    void move() { /* реализация */ } 
}

Ответ 18+ 🔞

Э, слушай, тут один чувак на собеседовании такую дичь сморозил про интерфейсы и абстрактные классы, что я сам от себя охуел. Давай разберём, чтобы ты такой же пизда с ушами не выглядел.

Короче, представь, что тебе нужно описать какую-то хуйню в коде. Есть два пути.

Первое — наследование. Это вообще пиздец какой важный момент. Класс твой может наследоваться только от одного абстрактного класса. Как будто у тебя один отец, и всё, других не бывает. А вот интерфейсов он может на себя нацепить сколько угодно — хоть десять, хоть овердохуища. Как будто ты и спортсмен, и музыкант, и ещё хуй с горы.

Второе — что внутри. Вот тут разница на лицо, точнее, в коде.

  • Абстрактный класс — это почти обычный класс, просто немного недоделанный. Он может иметь поля (переменные), конструкторы, и часть методов у него может быть уже с готовой реализацией. Удобно, когда у тебя есть общая логика для кучи похожих объектов.
  • Интерфейс — это по сути контракт, список требований. Раньше он мог содержать только заголовки методов (сигнатуры), без единой строчки кода внутри. Но потом умные дядьки из Oracle подумали и сказали: «Ёпта, давайте добавим default и static методы». И теперь в интерфейсе тоже можно писать код, но поля-переменные (не константы) — нихуя. Только public static final константы.

Третье — состояние. Абстрактный класс может хранить состояние объекта в своих полях. Интерфейс — нет. Он про поведение, а не про данные.

Смотри на примере, тут всё станет ясно. Представь, что мы делаем графический редактор для мартышлюшек.

// Интерфейс — контракт "Я умею рисоваться"
interface Drawable {
    void draw(); // абстрактный метод — ОБЯЗАН реализовать тот, кто подпишет контракт

    default void resize() { 
        // default-метод — уже с реализацией, можно переопределить, а можно и нет
        System.out.println("Изменяю размер... условно");
    }
}

// Абстрактный класс — базовая "Фигура" с какой-то общей хуйней
abstract class Shape {
    protected int x, y; // Поля, состояние! Где находится фигура.

    abstract void area(); // абстрактный метод — наследники ОБЯЗАНЫ посчитать площадь

    void move() { 
        // обычный метод с реализацией
        System.out.println("Двигаю фигуру из (" + x + "," + y + ")");
    } 
}

Вот и вся магия. Абстрактный класс — когда у объектов есть явная общая родня и общая логика. Интерфейс — когда нужно заставить разные, абсолютно непохожие объекты делать одно и то же действие («рисоваться», «сохраняться», «издавать звук»).

Выбирай с умом, а то получится хитрая жопа, которую потом на поддержку другому челу подкинешь, а он тебе волнение ебать устроит.

Видео-ответы