В Java 8 появилось понятие default methods — это методы с реализацией, объявленные внутри интерфейса. Они позволяют добавлять новые методы в интерфейсы, не нарушая совместимость с существующими реализациями.
Синтаксис:
public interface MyInterface { default void printHello() { System.out.println("Hello!"); } }
Особенности и тонкости:
Object (например, equals, hashCode).Что произойдёт, если класс реализует два интерфейса с одинаковым default-методом и не переопределяет этот метод?
Ответ: Компилятор выдаст ошибку "class... inherits unrelated defaults for ... from types ... and ...", и потребуется явно реализовать этот метод в классе.
Пример:
interface A { default void doSomething() { System.out.println("A"); } } interface B { default void doSomething() { System.out.println("B"); } } class C implements A, B {} // Ошибка компиляции!
Решение:
class C implements A, B { @Override public void doSomething() { A.super.doSomething(); // или B.super.doSomething() } }
История
В командном проекте для миграции API добавили default-метод в общий интерфейс. Старые реализации интерфейса не переопределяли новый метод, что привело к неожиданному поведению, поскольку выполнялась дефолтная реализация вместо ожидаемой логики. В результате пользователи заметили падение функциональности.
История
При расширении библиотеки один из разработчиков добавил default-метод с бизнес-логикой в общий интерфейс. Последующее добавление такого же метода с другим поведением в другой интерфейс вызвало конфликт наследования, что не позволило скомпилировать новые реализации.
История
Разработчик попытался использовать default-метод с именем
hashCodeв интерфейсе, ожидал, что это повлияет на переопределение метода в классах-наследниках, но компилятор не позволил этого сделать. Это привело к долгому разбирательству причин ошибки и переработке структуры интерфейсов.