Разработчики языка уже думали об этом, так что эти вещи выполняются компилятором.Поэтому, если вы определите:
interface First {
default void go() {
}
}
interface Second {
default void go() {
}
}
И вы реализуете класс для обоих интерфейсов:
static class Impl implements First, Second {
}
, вы получите ошибку компиляции;и вам нужно переопределить go
, чтобы не создавать двусмысленность вокруг него.
Но вы можете подумать, что вы можете обмануть компилятор, выполнив:
interface First {
public default void go() {
}
}
static abstract class Second {
abstract void go();
}
static class Impl extends Second implements First {
}
Вы можете подумать, что First::go
уже обеспечивает реализацию для Second::go
, и это должно бытьхорошо.Об этом слишком заботятся, и поэтому не компилируются.
JLS 9.4.1.3: Точно так же, когда наследуются абстрактный метод и метод по умолчанию с совпадающими сигнатурами, мы выдаем ошибку.В этом случае можно было бы отдать приоритет тому или другому - возможно, мы предположили бы, что метод по умолчанию обеспечивает разумную реализацию и для абстрактного метода.Но это рискованно, поскольку кроме совпадения имени и подписи, у нас нет оснований полагать, что метод по умолчанию ведет себя согласованно с контрактом абстрактного метода - метод по умолчанию, возможно, даже не существовал, когда изначально был разработан подинтерфейс .В этой ситуации безопаснее попросить пользователя активно утверждать, что реализация по умолчанию является подходящей (через переопределяющую декларацию).
Последний пункт, который я хотел бы привести, чтобы подтвердить, что множественное наследование не являетсяДопускается даже с новыми добавлениями в Java, является то, что статические методы от интерфейсов не наследуются.статические методы по умолчанию наследуются :
static class Bug {
static void printIt() {
System.out.println("Bug...");
}
}
static class Spectre extends Bug {
static void test() {
printIt(); // this will work just fine
}
}
Но если мы изменим это для интерфейса (и вы можете реализовать несколько интерфейсов, в отличие от классов):
interface Bug {
static void printIt() {
System.out.println("Bug...");
}
}
static class Spectre implements Bug {
static void test() {
printIt(); // this will not compile
}
}
Теперь это запрещено компилятором и JLS
:
JLS 8.4.8: класс не наследует статические методы от своих суперинтерфейсов.