Интерфейсы 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 без обязательного изменения каждой реализации. Правила выбора:
- метод класса имеет приоритет над default-методом;
- более конкретный дочерний интерфейс имеет приоритет;
- конфликт несвязанных 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.
Вопросы для собеседования
- Может ли интерфейс иметь реализацию метода? Да: default, static и private.
- Какие модификаторы у поля? Неявно
public static final. - Как разрешается конфликт default-методов? Реализация переопределяет
метод и при необходимости вызывает
Interface.super.method(). - Чем интерфейс отличается от абстрактного класса? Нет состояния экземпляра и конструкторов, зато допускается множественная реализация.
- Что такое functional interface? Интерфейс с одним абстрактным методом.
- Наследуется ли static-метод интерфейса как метод объекта? Нет, его вызывают через имя интерфейса.
- Зачем sealed interface? Ограничить известный набор реализаций.