Вопрос проверяет понимание default-методов в Java 8 и их влияние на определение функциональных интерфейсов.
В Java 8 появились default-методы (методы по умолчанию) в интерфейсах, которые имеют реализацию. Это важное изменение, но оно не нарушает определение функционального интерфейса.
Функциональный интерфейс — это интерфейс, который содержит ровно один абстрактный метод (Single Abstract Method — SAM). Именно этот единственный абстрактный метод определяет контракт, который можно реализовать с помощью лямбда-выражения или ссылки на метод.
Default-методы имеют тело (реализацию) и помечаются ключевым словом default. Они не являются абстрактными, поэтому не учитываются при подсчёте абстрактных методов. Это позволяет добавлять новую функциональность в интерфейсы, не нарушая обратной совместимости с классами, которые уже реализуют этот интерфейс.
Рассмотрим интерфейс Calculator, который является функциональным, несмотря на наличие default-метода.
@FunctionalInterface
interface Calculator {
// Единственный абстрактный метод — SAM
int calculate(int x, int y);
// Default-метод — имеет реализацию, не абстрактный
default void printResult(int x, int y) {
System.out.println("Result: " + calculate(x, y));
}
}
public class Main {
public static void main(String[] args) {
// Лямбда реализует абстрактный метод calculate
Calculator adder = (a, b) -> a + b;
System.out.println(adder.calculate(5, 3)); // 8
adder.printResult(5, 3); // Вызов default-метода
}
}Интерфейс Calculator помечен аннотацией @FunctionalInterface, что гарантирует наличие только одного абстрактного метода. Метод printResult — default, поэтому он не нарушает это правило.
stream(), forEach()) в интерфейсы Collection, List, не ломая существующие реализации.Predicate, Function) вспомогательными методами, сохраняя их пригодность для лямбда-выражений.Вывод: Default-методы — это мощный инструмент для эволюции интерфейсов в Java. Они не влияют на статус интерфейса как функционального, поскольку не являются абстрактными. Используйте их, когда нужно добавить новую функциональность в интерфейс, не нарушая существующий код, особенно при работе с лямбда-выражениями и Stream API.