Кандидат на сеньора часто отвечает на вопрос про 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 — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки