2016-06-19 14 views
3

私はJava 8を勉強していますが、私は完全に理解できないdefaultメソッドで動作を検出しました。継承されたdefaultメソッドは、継承されたクラスメソッドのような別のインターフェイスを実装できないのはなぜですか?

まず、コンパイルし、完璧に動作します「古い学校」のJavaスニペット:

abstract class A { 
    public void print() { 
     System.out.println("A"); 
    } 
} 
interface B { 
    void print(); // implicitly public and abstract 
} 
class C extends A implements B { 
    public void useInheritedPrint() { 
     print(); // prints A 
    } 
} 

CAから実装print()と正しく実装されたと見なされBから抽象print()を継承します。

しかしAinterfacedefaultと方法print()になった場合、次のようにまだAからprint()継承

interface A { 
    default void print() { // implicitly public 
     System.out.println("A"); 
    } 
} 
interface B { 
    void print(); // implicitly public and abstract 
} 
class C implements A,B { 
    public void useInheritedPrint() { 
     print(); // should print A 
    } 
} 

でもCかかわらず、コンパイラはCはないabstract(同じことがないという事実について不平を言います前述のようにAがクラスの場合に発生します)。 Cabstractなった場合は、次のように:

abstract class C implements A, B { 
    public void useInheritedPrint() { 
    print(); 
    } 
} 

を、コンパイラが実際文句Cは(Bから)defaultAから)とabstractprint()の両方を継承します。

class C implements A,B { 
    public void useInheritedPrint() { 
     print(); // should print A 
    } 
    public abstract void print(); // shall be implemented by a concrete subclass 
} 

またはprint()を無効にする:

解決策として、Cabstract print()を定義することのいずれかであるこの非対称のための特別な理由がある場合

class C implements A,B { 
    public void useInheritedPrint() { 
     print(); // should print A 
    } 
    public void print() { 
     // do something 
    } 
} 

誰もが知っていますinterfaceからdefault methodを継承し、それを親クラスから継承する間の動作は?

ここで何とか致命的な死のダイヤモンドが関わっていますか(私にはわかりません)?

答えて

2

あなたがCでprint()を実装する必要があります。

class C implements A,B { 
    public void useInheritedPrint() { 
     print(); // should print A 
    } 

    @Override 
    public void print() { 
     A.super.print(); 
    } 
} 

根拠はあなたが同じシグネチャを持つ2つの可能性の相反するメソッドを継承した場合、あなたが明示的にメソッドを実装し、(実装の1つを選択する必要があり、ということですまたは新しいものを定義する)。

+0

私が必要と知っている、私はなぜ尋ねた。 – 1d0m3n30

+3

言語設計者は、それを実現することなく実装を誤って継承することを避けるために、そのように設計することを選択したからです。 –

+0

私は同意しません、もし両方がデフォルト(=身体付き)である場合にのみ、同じ署名で2つの矛盾するメソッドを持つことができます。この状況では、Javaはそれらを実装するクラスにメソッドをオーバーライドさせますコンパイル)。しかし、私の状況は、Bのprint()の2つのうちの1つが抽象であるため、そのようには見えないので、矛盾はありません。 – 1d0m3n30

関連する問題