public interface MyCollection<E> extends Collection<E> { @Override default boolean isEmpty() { return !iterator().hasNext(); } //provide more default overrides below... } public interface MyList<E> extends MyCollection<E>,List<E> { @Override default Iterator<E>iterator(){ return listIterator(); } //provide more list-specific default overrides below... }
然而,即使这个简单的例子也遇到了一个编译错误:
error: interface MyList<E> inherits abstract and default for isEmpty() from types MyCollection and List
从我对默认方法的理解,应该允许这样做,因为只有一个扩展接口提供了默认实现,但显然不是这样.这里发生了什么?有没有办法得到这样做我想要的?
解决方法
It is possible for an interface to inherit several methods with override-equivalent signatures (§8.4.2).
…
Similarly,when an abstract and a default method with matching signatures are inherited,we produce an error. In this case,it would be possible to give priority to one or the other – perhaps we would assume that the default method provides a reasonable implementation for the abstract method,too. But this is risky,since other than the coincidental name and signature,we have no reason to believe that the default method behaves consistently with the abstract method’s contract – the default method may not have even existed when the subinterface was originally developed. It is safer in this situation to ask the user to actively assert that the default implementation is appropriate (via an overriding declaration).
因此,既然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(); } ... }