Интерфейсы Java

Интерфейс задаёт контракт типа без состояния экземпляра. Класс может реализовать несколько интерфейсов, поэтому интерфейсы используются для полиморфизма, границ модулей и подменяемых реализаций.

interface Clock {
    Instant now();
 
    default boolean isAfter(Instant moment) {
        return now().isAfter(moment);
    }
}
 
final class SystemClock implements Clock {
    public Instant now() {
        return Instant.now();
    }
}

Метод реализации обязан быть public: нельзя ослабить доступ по сравнению с неявно public-методом интерфейса.

Что разрешено объявлять

ЭлементМодификаторы по смыслу
полеpublic static final
метод без телаpublic abstract
default-методpublic default
static-методпринадлежит интерфейсу
private-методобщий код default/static методов, Java 9+
вложенный типpublic static

У интерфейса нет конструктора и изменяемых полей экземпляра. Поля являются константами; прятать в них изменяемую коллекцию опасно, потому что final фиксирует ссылку, а не состояние объекта.

Default methods и конфликты

Default-методы позволяют развивать API без обязательного изменения каждой реализации. Правила выбора:

  1. метод класса имеет приоритет над default-методом;
  2. более конкретный дочерний интерфейс имеет приоритет;
  3. конфликт несвязанных default-методов класс разрешает явно.
interface Left  { default String id() { return "L"; } }
interface Right { default String id() { return "R"; } }
 
final class Both implements Left, Right {
    public String id() {
        return Left.super.id() + Right.super.id();
    }
}

Функциональные и sealed interfaces

Функциональный интерфейс имеет один абстрактный метод и может быть целью lambda. Методы Object, default и static не увеличивают это число. @FunctionalInterface просит компилятор проверить контракт.

С Java 17 интерфейс может быть sealed и перечислять разрешённые реализации. Это ограничивает иерархию, но не превращает интерфейс в класс с состоянием.

Интерфейс выражает способность или роль; абстрактный класс удобнее, когда нужно общее состояние, защищённые методы или конструктор.

Связанные темы: Обобщения generics, О языке Java, Нововведения Java 17.

Вопросы для собеседования

  1. Может ли интерфейс иметь реализацию метода? Да: default, static и private.
  2. Какие модификаторы у поля? Неявно public static final.
  3. Как разрешается конфликт default-методов? Реализация переопределяет метод и при необходимости вызывает Interface.super.method().
  4. Чем интерфейс отличается от абстрактного класса? Нет состояния экземпляра и конструкторов, зато допускается множественная реализация.
  5. Что такое functional interface? Интерфейс с одним абстрактным методом.
  6. Наследуется ли static-метод интерфейса как метод объекта? Нет, его вызывают через имя интерфейса.
  7. Зачем sealed interface? Ограничить известный набор реализаций.