Ответ 1
Это объясняется в разделе раздел 9.4.1.3 (Наследование методов с переопределяющими эквивалентными сигнатурами) Спецификации языка Java:
Интерфейс может наследовать несколько методов с переопределяющими эквивалентными сигнатурами (§8.4.2).
...
Аналогично, когда абстрактный метод и метод по умолчанию с соответствующими сигнатурами наследуются, мы создаем ошибку. В этом случае можно было бы отдать приоритет одному или другому - возможно, мы предположили бы, что метод по умолчанию обеспечивает разумную реализацию абстрактного метода. Но это рискованно, потому что, помимо имени совпадения и подписи, у нас нет оснований полагать, что метод по умолчанию ведет себя последовательно с контрактом абстрактного метода - метод по умолчанию, возможно, даже не существовал, когда исходный интерфейс был первоначально разработан. В этой ситуации безопаснее просить пользователя активно утверждать, что реализация по умолчанию является подходящей (через переопределяющее объявление).
Итак, поскольку оба MyCollection
и List
определяют метод isEmpty()
, а один - по умолчанию, а другой абстрактный, компилятор требует, чтобы подпоследователь явно указывал, какой из них он должен наследовать, переопределив метод еще раз. Если вы хотите, чтобы метод по умолчанию MyCollection
был унаследован, вы можете вызвать его в переопределяющей реализации:
public interface MyList<E> extends MyCollection<E>, List<E> {
@Override default boolean isEmpty() {
return MyCollection.super.isEmpty();
}
@Override default Iterator<E> iterator(){
return listIterator();
}
...
}
Если вы хотите, чтобы MyList
сохранял тег isEmpty()
(который, как я думаю, вы не хотите), вы можете сделать:
public interface MyList<E> extends MyCollection<E>, List<E> {
@Override boolean isEmpty();
@Override default Iterator<E> iterator(){
return listIterator();
}
...
}