加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 16:24:25 所属栏目:Java 来源:网络整理
导读:我正在尝试使用 Java 8中的新的默认方法语法编写一个收集接口库,以实现标准Collection API中的大多数方法.以下是我要做的一个小样本: public interface MyCollectionE extends CollectionE { @Override default boolean isEmpty() { return !iterator().has
我正在尝试使用 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();
    }
    ...
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读