Кандидат на сеньора часто отвечает на вопрос про default-методы так: «это способ сделать множественное наследование в Java». Формально звучит похоже, но интервьюер в этот момент проверяет не память о синтаксисе, а понимание, что именно наследуется.
У класса нет состояния от default-метода — только поведение, и то если его не переопределили. Если класс реализует два интерфейса с одинаковой сигнатурой default-метода, компилятор не выбирает один автоматически: он требует явно переопределить метод и решить конфликт руками. Это не ромбовидное наследование C++, это явное требование разрешить коллизию поведения.
Default-методы появились в Java 8 не для наследования вообще, а для эволюции интерфейсов: можно было добавить новый метод в существующий интерфейс (например, forEach в Collection) и не сломать все классы, которые его уже реализуют.
interface Flyer { default String move() { return "flying"; } }
interface Swimmer { default String move() { return "swimming"; } }
class Duck implements Flyer, Swimmer { // обязателен override — иначе ошибка компиляции public String move() { return Flyer.super.move() + " and " + Swimmer.super.move(); } }
Следующий вопрос обычно: «а что если один интерфейс наследует другой с тем же default-методом?» Тогда конфликта нет — более специфичный интерфейс просто переопределяет метод родителя, компилятор выбирает ближайшего по иерархии. Конфликт возникает только между двумя независимыми интерфейсами одного уровня.
Default-метод — это contract evolution, а не альтернатива extends.
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки