Ответ
Default-методы (методы по умолчанию) — это методы в интерфейсе Java, имеющие реализацию. Они были введены в Java 8 с ключевым словом default.
Основная решаемая проблема: Эволюция интерфейсов без нарушения обратной совместимости. До Java 8 добавление любого нового метода в интерфейс ломало все существующие классы, его реализующие, так как требовало немедленной реализации. Default-методы позволяют добавлять новую функциональность в интерфейсы, предоставляя готовую реализацию "по умолчанию", которую классы могут унаследовать или переопределить.
Синтаксис и пример:
interface Vehicle {
// Абстрактный метод (обязателен для реализации)
void start();
// Default-метод (уже имеет реализацию)
default void honk() {
System.out.println("Beep beep from the interface!");
}
// Еще один default-метод (помощник)
default String getFuelType() {
return "Generic fuel";
}
}
class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car engine started.");
}
// Метод honk() НЕ переопределен, будет использована default-реализация.
}
// Использование
Vehicle myCar = new Car();
myCar.start(); // Вывод: Car engine started.
myCar.honk(); // Вывод: Beep beep from the interface!
Ключевые правила и особенности:
- Переопределение: Класс, реализующий интерфейс, может переопределить default-метод, изменив его поведение.
- Конфликт множественного наследования: Если класс реализует два интерфейса с одинаковыми default-методами, возникает неоднозначность. Компилятор требует явного переопределения этого метода в классе, где можно вызвать нужную реализацию через
InterfaceName.super.methodName().interface A { default void foo() { System.out.println("A"); } } interface B { default void foo() { System.out.println("B"); } } class C implements A, B { @Override public void foo() { A.super.foo(); // Явно выбираем реализацию из A } } - Нет доступа к состоянию: Default-методы не имеют доступа к приватным полям класса, который их реализует. Они могут работать только с данными, доступными через другие методы интерфейса.
- Не могут переопределять методы Object: Интерфейс не может объявить default-реализацию для
equals,hashCodeилиtoString— это вызовет ошибку компиляции.