0

Java でクラスの循環継承が許可されない理由は理解できましたが、インターフェースの循環継承が許可されない理由は理解できませんでした。説明する:

interface Foo extends Bar {/*methods and constants*/}

interface Bar extends Foo {/*methods and constants*/}

インターフェースはインスタンス化を必要としないのに、相互に拡張するのを妨げるものは何ですか?

ところで、私はこの質問を読みましたが、これはインターフェイスではなくクラスに関するものです: Java の巡回継承階層

前もって感謝します。

4

3 に答える 3

3

いいえ。ただし、インターフェースの拡張は契約を分割する方法です。インターフェースは、一連のメソッドの実装を提供する合意であることを思い出してください。

public interface A extends B {
    public void myMethod();
    public void myOtherMethod();
}

Aインターフェイスは、これらのメソッドとインターフェイス内のすべてのメソッドによって定義されていると言っていますB。インターフェイスBが次のように言う場合..

public interface B extends A {}

Bインターフェイスはインターフェイスのメソッドによって定義されていると言っていますA。さて、インターフェイスを定義するものA。いくつかのメソッドとインターフェースB。インターフェイスを定義するものは何Bですか? Aいくつかのメソッドと interface によって定義されるInterface B! これがどこに向かっているのかわかりますか?

これを許可することは論理的に意味がありません。

于 2016-02-08T13:00:45.273 に答える
1

おそらく理論上の問題はありませんが、これは不必要な複雑さを生み出します。いくつか挙げてみましょう:

  • 現在、( の再帰呼び出しによるClass.getInterfaces()) クラス インターフェイスのトラバーサルは、おそらく繰り返しを伴う有限の結果を生成することが保証されていますが、それでもなおです。たとえば、次のようなコードは有効です。

    private static void fillInterfaces(Class<?> clazz, Set<Class<?>> set) {
        if(clazz == null) return;
        for (Class<?> iclass : clazz.getInterfaces()) {
            set.add(iclass);
            fillInterfaces(iclass, set);
        }
        fillInterfaces(clazz.getSuperclass(), set);
    }
    
    public static Set<Class<?>> getAllInterfaces(Class<?> clazz) {
        Set<Class<?>> result = new HashSet<>();
        fillInterfaces(clazz, result);
        return result;
    }
    

    同様のコードがすでに書かれており、多くの場所で機能しています。ここで循環インターフェースを提供する提案では、無限再帰が発生します。

  • 現在 (Java-8 では) インターフェイスは、必要に応じて親の実装を置き換えて、親インターフェイスのデフォルトの実装も定義できます。例えば:

    interface A {
        default public String getX() {return "A";}
    }
    
    interface B extends A {
        default public String getX() {return "B";}
    }
    
    static class C implements A, B {} // ok, C.getX() returns "B"
    

    nowA extends Bの場合、次Aが勝ちます。

    interface A extends B {
        default public String getX() {return "A";}
    }
    
    interface B {
        default public String getX() {return "B";}
    }
    
    static class C implements A, B {} // ok, C.getX() returns "A"
    

    しかし、 と の両方の場合はどうなるA extends BでしょB extends Aうか。誰が勝つ?何new C().getX()を印刷しますか?それとも、新しいタイプのコンパイル エラーでしょうか?

一般に、そのような機能はメリットよりも多くの問題をもたらすように思われます。

于 2016-02-11T08:22:08.073 に答える