Метод суперкласса и разрешение по умолчанию метода интерфейса по умолчанию

Рассмотрим приведенный ниже пример,

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 сообщается иначе, как показано в приведенном ниже снимке экрана.

Я твердо верю, что это ошибка в Eclipse.

Но прежде, чем предположить, это поведение определено и задокументировано в JLS? Или есть что-то другое, определяющее это поведение?

Изменить: версия Eclipse Mars Release (4.5.0), если это имеет значение.

3 ответа

Ваше предположение верно, конкретный метод, унаследованный от суперкласса, имеет приоритет над методом default из interface:

JLS §8.4.8. Наследование, переопределение и скрытие

Класс C наследует от его прямого суперкласса и прямых суперинтерфейсов все abstract и методы по умолчанию (§9.4) m, для которых все из следующих утверждений: true/

...

  • Никакой метод, объявленный в C, не имеет сигнатуры, которая является поднаклейкой (§8.4.2) сигнатуры m.
  • Никакой конкретный метод, унаследованный C от его прямого суперкласса, имеет подпись, которая является подзаглавлением сигнатуры m.

Здесь применяется вторая цитированная марка, существует конкретный метод, унаследованный от прямого суперкласса с соответствующей сигнатурой, поэтому метод default не наследуется.

В документации даже устранены сомнения с дополнительным примечанием:

Обратите внимание, что унаследованный конкретный метод может предотвратить наследование абстрактного метода или метода по умолчанию. (Позже мы будем утверждать, что конкретный метод переопределяет абстрактный или дефолтный метод "от C".)

Таким образом, его как SupCls.test() переопределяет Intf.test(), когда дело доходит до класса Testing.

Другими словами, вы правы, это ошибка в Eclipse, но пока это влияет только на способ рендеринга предложения, Id считает это незначительной ошибкой. Вставляемый источник будет таким же, независимо от того, был ли предоставлен D в предложении или нет.


Это, безусловно, ошибка в eclipse, но в предложениях по завершению кода, а не в компиляторе. При наведении указателя на вызов или Open Declaration вы переходите к методу SupCls и правильно запускаете код "От SupCls", что подтверждает это. Пожалуйста, зарегистрируйте ошибку против jdt ui для исследования


Похоже, что версия Eclipse имеет значение!

В Eclipse Luna (4.4.1) эталон указывает на SupCls вместо Intf

Вероятно, ошибка в Eclipse Mars

licensed under cc by-sa 3.0 with attribution.