17

Set と List を実装するクラスがあります。プログラムは Java6 および Java7 で正常に動作します

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

Java 8 では、これはコンパイルされません。エラーは

java: クラス trial.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 の両方を実装するクラスを持てないということですか? (技術的負債を支払う時が来たようです。)

4

3 に答える 3

12

Listクラスが と の両方を実装することはめったにありませんSetが、いくつかの状況では、Setがある程度限定された であることをサポートできListます。

個人的には、両方を同時にasList()実装するのではなく、これらの場合にメソッドを宣言することを好みます。このようなもの:ListSet

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

一方、 と の両方を実装する既存のクラスが既にある場合ListSet問題の最も簡単な解決策は、おそらくスーパーspliterator()メソッドの 1 つを明示的に呼び出すことです。

public class SetList<V> implements Set<V>, List<V> {
    @Override
    public Spliterator<V> spliterator() {
        return List.super.spliterator();
    }
}
于 2014-03-31T13:17:21.037 に答える
8

これは、多重継承で発生する Diamond Problem です

「ダイアモンド問題」(「致命的な死のダイアモンド」とも呼ばれる) は、2 つのクラス B と C が A から継承し、クラス D が B と C の両方から継承するときに発生するあいまいさです。 B と C がオーバーライドし、D がそれをオーバーライドしない場合、D はメソッドのどのバージョンを継承しますか? B のメソッドと C のメソッドのどちらですか?

Java では、コンパイル エラーによってこの問題が回避されます。これを解決するには、あなたのものを実装する必要があります

于 2016-09-17T07:20:01.900 に答える