2017-11-12 10 views
1

コードがコンパイルされていませんに従い、Line 1インタフェースと共変戻り値の型

戻り値の型で、次のエラーを与えているがB.m1()

interface A { 
    Object m1(); 
} 

interface B { 
    String m1(); 
} 

abstract class C implements A,B { 
    @Override 
    public Object m1() //Line 1 
    { 
     return new Object(); 
    } 
} 

class D extends C { 

    @Override 
    public String m1() { 
     return ""; 
    } 

} 

、私のクエリと互換性がありませんObjectStringcovariantclass Cは抽象クラスです。ABの両方を実装していますが、なぜこのコンパイルエラーがあるのですか?インタフェースメソッド。

+0

あなたがリターンとして、ボイドを置けば、それは –

+0

罰金に動作します入力することのようなものは何もありません、答えを見つけると私の疑問をクリアしようとしないの問題ください.. :) –

+1

'C'は動作しません。 'C'が' B'ならば、 'm1'から' String'を返すことを期待しています。だから、 'B'は' A'のように動作しますが、**はそうではありません。だから 'C'は動かない。 [Liskov](https://en.wikipedia.org/wiki/Liskov_substitution_principle)を参照してください。 –

答えて

1

Cは機能しません。

CBの場合は、Stringm1に戻すことを期待しています。したがってBAとして機能しますが、その逆はありません。だからCは動作しません。

final A a = new C(){}; 
final Object res = a.m1(); //fine, `m1` returns an `Object`. 

final B b = new C(){}; 
final String res = b.m1(); //bang 

は、ここでは、Bm1()からStringを返しますが、あなたの実装がObjectを返すことがわかります。このコンパイルでは、これが発生することはできません。

Liskov substitution principleを参照してください。 CBの場合、私はBをどこにでも持っています。私はこれをCに置き換えることができます。あなたの例ではそうではありません。


これはうまくいくでしょう - なぜ表示されますか?

abstract class C implements A, B { 
    @Override 
    public String m1() { 
     return ""; 
    } 
} 
+0

はい、あなたは正しいです、これは働いています... :)奇妙な私はあなたの答えを確認して理解する必要があります –

+0

私はあなたに教えてください2番目のケースが動作している、理解できない –

+0

@LoneWolf私はそれが自分自身でそれを働かせることがより有用だろうと思う。 Liskovについて読んで、私が上記と同じロジックを適用してください。 –