JavaRush /Курсы /JAVA 25 SELF /Отличие интерфейсов от абстрактных классов

Отличие интерфейсов от абстрактных классов

JAVA 25 SELF
20 уровень , 1 лекция
Открыта

1. Абстрактный класс: повторим основы

Перед тем как перейти к сравнению, освежим в памяти, что же такое абстрактный класс.

Абстрактный класс — это класс, который не может быть создан напрямую (нельзя написать new Animal()), но может содержать как обычные (с реализацией), так и абстрактные (без реализации) методы. Абстрактный класс часто используется как основа для других классов, которые наследуют его поведение и/или обязаны реализовать некоторые методы.

Например, если в нашем приложении есть разные виды транспорта, можно завести абстрактный класс Transport:

public abstract class Transport {
    private String model;

    public Transport(String model) {
        this.model = model;
    }

    public String getModel() {
        return model;
    }

    // Абстрактный метод — реализации нет, только объявление
    public abstract void move();

    // Обычный метод — реализация есть
    public void printInfo() {
        System.out.println("Модель транспорта: " + model);
    }
}

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

  • Может содержать поля (состояние).
  • Может содержать реализованные методы.
  • Может содержать абстрактные методы (обязательные к реализации в наследниках).
  • Нельзя создать экземпляр напрямую.
  • Используется для общего поведения и состояния.

2. Интерфейс: повторим основы

Интерфейс — это набор методов, которые должен реализовать класс. Интерфейс не описывает состояние (не может иметь обычные поля, только константы), и не содержит реализации методов (до Java 8). Интерфейс — это чистый контракт: «Если ты реализуешь меня, ты обязан уметь делать вот это».

Пример интерфейса:

public interface Movable {
    void move(int x, int y);
}

Особенности интерфейса:

  • Не содержит состояния (только public static final константы).
  • До Java 8 — только абстрактные методы (с Java 8 появились default- и static-методы, но о них позже).
  • Методы всегда public abstract по умолчанию.
  • Класс может реализовать несколько интерфейсов.
  • Используется для описания возможностей, «что умеет делать» класс.

3. Таблица сравнения: абстрактный класс vs интерфейс

Пора сравнить эти два инструмента лицом к лицу! Вот наглядная таблица:

Особенность Абстрактный класс Интерфейс
Синтаксис
abstract class
interface
Можно создавать экземпляр? Нет Нет
Может содержать обычные методы? Да До Java 8 — нет, с Java 8 — только default/static
Может содержать абстрактные методы? Да Да (все методы до Java 8 абстрактные)
Может содержать поля (состояние)? Да (любые поля) Только public static final (константы)
Может содержать конструкторы? Да Нет
Наследование Только один абстрактный/обычный класс Можно реализовать несколько интерфейсов
Модификаторы методов Любые (public, protected, private) Методы по умолчанию public abstract. С Java 9 можно добавлять private методы для использования внутри интерфейса
Наследование через
extends
implements
Для чего обычно используется Общая реализация и состояние Описание возможностей, ролей
Примеры из JDK
AbstractList, AbstractMap
Comparable, Runnable

4. Когда использовать интерфейс, а когда абстрактный класс?

Интерфейс используйте, когда:

  • Вы хотите описать «что умеет делать» класс, не заботясь о том, как он это делает.
  • Вам нужно, чтобы класс мог реализовать несколько независимых возможностей.
  • Пример: Comparable (можно сравнивать), Serializable (можно сериализовать), Runnable (можно запускать в потоке).

Абстрактный класс используйте, когда:

  • Вы хотите задать общую реализацию и состояние, которые будут у всех наследников.
  • Вам нужно, чтобы все наследники имели определённые поля или методы с реализацией.
  • Наследование — строго «один к одному»: класс может наследовать только один класс (обычный или абстрактный).

Жизненные аналогии

  • Интерфейс — это как «водительские права»: если у тебя они есть, ты можешь водить машину, но никто не говорит, на какой именно машине и как ты это делаешь.
  • Абстрактный класс — это как «общий чертёж автомобиля»: у всех машин есть руль, педали, двигатель, но каждая марка реализует детали по-своему.

5. Примеры из стандартной библиотеки Java

Интерфейс: Comparable

public interface Comparable<T> {
    int compareTo(T o);
}

Любой класс, который реализует этот интерфейс, обязан реализовать метод compareTo. Например, String, Integer, LocalDate и многие другие.

Абстрактный класс: AbstractList

public abstract class AbstractList<E> implements List<E> {
    // Реализация некоторых методов List по умолчанию
    // Некоторые методы оставлены абстрактными
}

AbstractList уже реализует часть поведения коллекций (например, методы добавления/удаления), но оставляет некоторые методы абстрактными, чтобы наследники могли реализовать их по-своему.

6. Примеры кода: сравнение на практике

Интерфейс

Создадим интерфейс и класс, который его реализует.

public interface Printable {
    void print();
}

public class Document implements Printable {
    @Override
    public void print() {
        System.out.println("Печатаю документ...");
    }
}

Абстрактный класс

Теперь абстрактный класс и его наследник.

public abstract class Machine {
    public void turnOn() {
        System.out.println("Машина включена.");
    }

    public abstract void work();
}

public class Printer extends Machine {
    @Override
    public void work() {
        System.out.println("Принтер печатает...");
    }
}

Класс реализует оба: и интерфейс, и абстрактный класс

public class SmartPrinter extends Machine implements Printable {
    @Override
    public void work() {
        System.out.println("Умный принтер работает...");
    }

    @Override
    public void print() {
        System.out.println("Умный принтер печатает...");
    }
}

7. Множественная реализация интерфейсов: зачем это круто

В Java класс может наследовать только один класс (abstract или обычный), но реализовывать сколько угодно интерфейсов! Это позволяет создавать гибкие, расширяемые архитектуры.

public interface Scannable {
    void scan();
}

public class MultiFunctionPrinter extends Machine implements Printable, Scannable {
    @Override
    public void work() {
        System.out.println("МФУ работает...");
    }

    @Override
    public void print() {
        System.out.println("МФУ печатает...");
    }

    @Override
    public void scan() {
        System.out.println("МФУ сканирует...");
    }
}

Когда что выбирать ?

  • Если вы проектируете базовый функционал с общим состоянием (например, поля), используйте абстрактный класс.
  • Если вы хотите навесить на объекты «ярлыки возможностей» (например, «умеет печатать», «умеет сравниваться», «умеет сериализоваться») — используйте интерфейсы.
  • Если вы не уверены — начинайте с интерфейса. В Java это считается хорошим тоном: интерфейсы дают большую гибкость и расширяемость.

8. Типичные ошибки и подводные камни

Ошибка №1: Пытаетесь наследовать несколько классов — Java не даст!
Класс может наследовать только один класс, но реализовывать много интерфейсов. Например, class A extends B, C — ошибка, а вот class A extends B implements X, Y, Z — пожалуйста.

Ошибка №2: Путаете поля интерфейса и класса.
В интерфейсе можно объявлять только константы (public static final). Нельзя объявить обычное состояние, например, private int count; — компилятор тут же вас остановит.

Ошибка №3: Не реализовали все методы интерфейса.
Если класс не реализует хоть один метод интерфейса — он должен быть объявлен как abstract, иначе компилятор выдаст ошибку.

Ошибка №4: Пытаетесь создать экземпляр интерфейса или абстрактного класса.
Оба этих типа — «полуфабрикаты». Их можно только расширять, но нельзя создать напрямую:

Printable p = new Printable(); // Ошибка!
Machine m = new Machine();     // Ошибка!

Ошибка №5: Думаете, что интерфейс может иметь конструктор.
У интерфейсов не может быть конструкторов, так как они не описывают состояние объектов. Только у классов (обычных и абстрактных).

1
Задача
JAVA 25 SELF, 20 уровень, 1 лекция
Недоступна
Транспортная Компания: Единый Протокол Движения
Транспортная Компания: Единый Протокол Движения
1
Задача
JAVA 25 SELF, 20 уровень, 1 лекция
Недоступна
Университетский Реестр: Личности и Идентификаторы
Университетский Реестр: Личности и Идентификаторы
1
Задача
JAVA 25 SELF, 20 уровень, 1 лекция
Недоступна
Мультифункциональное Устройство Офиса
Мультифункциональное Устройство Офиса
1
Задача
JAVA 25 SELF, 20 уровень, 1 лекция
Недоступна
Смартфон: От Общих Устройств к Персональным Гаджетам
Смартфон: От Общих Устройств к Персональным Гаджетам
Комментарии (5)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
dansyrkin Уровень 21
10 января 2026
Зачем во второй задаче требуют объявить константу ID как public static final, если в интерфейсе это по умолчанию?
Ksanders Уровень 32
30 ноября 2025
Задача №2 максимально стремная - условия прописаны не явно, не указано что нужны геттер и сеттер, не указано в каком формате нужно выводить данные о студенте.
dansyrkin Уровень 21
10 января 2026
а зачем здесь геттер и сеттер? имя задается через конструктор, а значение просто забираем, если конечно не объявить переменную как private.
Ksanders Уровень 32
30 ноября 2025
А где наши любимы зверушки с makeSound? 😕😭
Xaxatumba Уровень 38
12 ноября 2025
Почему не сделать задачи в виде приложения для продажи шаурмы. С поэтапным разбором. Где можно разобрать пользовательскую часть и часть повара который видит заказы пользователей и готовит их. Или приложение блинной с тем же функционалом. Или если так нравиться Vechicle, то автосервис с приёмкой, диагностикой, подбором запчастей, ремонтом, и выдачей. Вариантов миллион из реальной жизни, а мы блин коров с котами заставляем мяукать и машины с велосипедами заставляем ехать. Складывается впечатление что данный курс учит не написанию кода по конкретной задаче, а отработки навыка копирования и вставки. Если вы хотите научить синтаксису то сделайте с десяток лекций в самом начале где будет тупо написано что Интерфейс в коде пишется так-то (с примерами на коровах), класс так-то (с примерами на машинках) и т.п. А уже потом разбирайте непосредственно, что такое Интерфейс и как с ним работать на нормальных примерах.