Метод суперкласса и разрешение конфликтов методов интерфейса по умолчанию
Рассмотрим приведенный ниже пример,
public class Testing extends SupCls implements Intf {
public static void main(String[] args) {
new Testing().test();
}
}
class SupCls {
public void test() {
System.out.println("From SupCls");
}
}
interface Intf {
public default void test() {
System.out.println("From Intf");
}
}
Как видите, нет никакой связи между SupCls
класс и Intf
интерфейс. Но оба определяют общий метод.
А также Testing
класс расширяется SupCls
и внедрение Intf
,
Итак, когда я звоню test()
метод на Testing
выход есть,
From SupCls
Что, я думаю, имеет смысл, поскольку расширение из класса должно иметь более высокий приоритет, чем реализация из интерфейса.
Но затмение сообщает иначе, как показано на снимке экрана ниже.
Я твердо верю, что это ошибка в Eclipse.
Но прежде чем предположить, определено ли и описано ли это поведение в JLS? Или есть что-то еще, что определяет это поведение?
Редактировать: Версия Eclipse - Mars Release (4.5.0), если это имеет значение.
3 ответа
Ваше предположение верно, конкретный метод, унаследованный от суперкласса, имеет приоритет над default
метод из interface
:
JLS §8.4.8. Наследование, переопределение и сокрытие
Класс
C
наследует от своего прямого суперкласса и прямых суперинтерфейсов всеabstract
и методы по умолчанию (§9.4)m
для которого выполняются все следующие условия:...
- Ни один метод не объявлен в
C
имеет подпись, которая является подписью (§8.4.2) подписиm
,- Нет конкретного метода, унаследованного
C
от его прямого суперкласса есть подпись, которая является подписью подписиm
,
Здесь применяется вторая упомянутая пуля, есть конкретный метод, унаследованный от прямого суперкласса с соответствующей сигнатурой, поэтому default
метод не наследуется.
Документация даже устраняет любые сомнения с дополнительным замечанием:
Обратите внимание, что унаследованный конкретный метод может предотвратить наследование абстрактного метода или метода по умолчанию. (Позже мы будем утверждать, что конкретный метод переопределяет абстрактный метод или метод по умолчанию "из C".)
Так как SupCls.test()
Переопределение Intf.test()
когда дело доходит до класса Testing
,
Другими словами, вы правы, это ошибка в Eclipse, но пока она влияет только на способ визуализации предложения, я бы посчитал это незначительной ошибкой. Вставленный источник будет одинаковым независимо от того, был ли D представлен в предложении или нет.
Это, безусловно, ошибка в eclipse, но в предложениях по завершению кода, а не в компиляторе. При наведении указателя мыши на вызов test или Open объявлений вы переходите к методу SupCls, и при правильном запуске кода выводится "From SupCls", что подтверждает это. Пожалуйста, отправьте сообщение об ошибке в JDT UI для расследования
Похоже, версия затмения имеет значение!
В Eclipse Luna (4.4.1) указатели на SupCls
вместо Intf
Вероятно, ошибка в Eclipse Mars