类从 java.util.Set 和 java.util.List 类型继承 spliterator() 的不相关默认值

2022-09-03 01:42:29

我有实现 Set 和 List 的类。程序在 Java6 和 Java7 中工作正常

public class SetList<V> implements Set<V>, List<V>
{
  ....
}

在Java 8中,这不能编译。错误是

java:类试验。SetList 从 java.util.Set 和 java.util.List 类型继承 spliterator() 的不相关默认值

java/util/Set.java:394

 ...
@Override
default Spliterator<E> spliterator() {
    return Spliterators.spliterator(this, Spliterator.DISTINCT);
}

java/util/List.java

...
@Override
default Spliterator<E> spliterator() {
    return Spliterators.spliterator(this, Spliterator.ORDERED);
}

这是否意味着我不能在Java 8中同时实现Set和List的类?(看起来是时候偿还我们的技术债务了。


答案 1

虽然一个类同时实现 和 是不寻常的,但在某些情况下,a 也可以支持在某种程度上受到限制。ListSetSetList

就个人而言,在这些情况下,我更喜欢声明一个方法,而不是同时实现两者。像这样:asList()ListSet

public class SetList<V> implements Set<V> {
    public List<V> asList(){
        // return a list representation of this Set
    }
}

另一方面,如果您已经有一个现有的类,该类同时实现 和 ,那么您的问题的最简单解决方案可能是显式调用其中一个超级方法:ListSetspliterator()

public class SetList<V> implements Set<V>, List<V> {
    @Override
    public Spliterator<V> spliterator() {
        return List.super.spliterator();
    }
}

答案 2

这是多重继承中导致的钻石问题

“钻石问题”(有时被称为“致命的死亡钻石”)是当两个B类和C类从A继承,而D类同时从B和C继承时出现的歧义。如果 A 中有一个 B 和 C 已覆盖的方法,并且 D 没有覆盖它,那么 D 继承了该方法的哪个版本:B 的那个版本,还是 C 的那个版本?

在 Java 中,编译错误可以防止此问题。为了解决这个问题,你应该实现你的一个


推荐