Java 8错误:接口继承抽象和默认

我正在尝试使用 Java 8中的新的方法语法编写一个收集接口库,以实现标准Collection API中的大多数方法.以下是我要做一个小样本:
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

从我对方法的理解,应该允许这样做,因为只有一个扩展接口提供了认实现,但显然不是这样.这里发生了什么?有没有办法得到这样做我想要的?

解决方法

这在Java语言规范的 section 9.4.1.3 (Inheriting Methods with Override-Equivalent Signatures)中有所解释:

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();
    }
    ...
}

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...