1

このコードは無効です:

interface Foo
{
    public void foo(final String string);
}

public class Bar implements Foo
{
    // Error: does not override.
    @Override public void foo(final Object object)
    {
    }
}

everyStringは明らかに であるためObject、このコードは完全に問題ないと思いますfoo()String実際foo()Object.

ただし、メソッド シグネチャは、オーバーライドするメソッドのシグネチャと同一でなければならないようです。なんで?

4

4 に答える 4

4

仮に

interface Foo
{
    void foo(String string);
    void foo(Object string);
}

次に、どのメソッドがBarによってオーバーライドされますか?

于 2012-04-09T01:01:10.827 に答える
0

あなたが言うように「緩める」ことは、特定の方法でインターフェイスで定義されたメソッドを使用することを期待している誰かに影響を与えるべきではありません。そのオブジェクトで呼び出すメソッドは、理論的には指定されたオブジェクトで呼び出すことができるはずですが、インターフェイスの仕様に漠然と固執したいだけの場合、実際にオーバーライドするつもりだったメソッドを決定する際に対処するコンパイラの頭痛の種になるでしょう。また、継承階層を上に移動することに固執する場合、これが望ましいのはなぜですか。たとえば、「オブジェクト」のように、階層のさらに下にあるものに対してやりたいことをすべて実行できるからです。メソッド内でキャストすることで問題が解決する可能性がありますか? やりたいことができるなら、

于 2012-04-09T01:23:17.433 に答える
0

これは古典的な反変性の問題だと思います。あなたのインターフェイスは文字列をパラメーターとして渡す必要があります。オブジェクトを受け入れる実装が必要です (結局のところ、文字列もオブジェクトであるため)。

問題は、それを許可した場合、インターフェイスが必要とするパラメーターが文字列またはその祖先のいずれかであることを保証できなくなることです。任意のオブジェクトを実装に渡すのと同じように、インターフェイスの契約を破ることになり、設計の型の安全性と型の一貫性が危険にさらされます。

ただし、次のオプションがあります。

public class Bar implements Foo
{

    @Override public void foo(final String object)
    {
    }

    public void foo(final Object object)
    {
       foo((String) object);
    }
}

これにより、オブジェクトが実際に文字列であることを確認し、型システムがメソッド シグネチャで確立されたインターフェイス コントラクトに実際に準拠していることを確認できるようになります。

反変性の例が要件であると考える特定のシナリオはありますか?

于 2012-04-09T01:27:34.667 に答える
0

これは、Java プログラミング言語の構成要素にすぎません。Java プログラムの構造はあなた次第です。なので、とりあえず調整してみてください。

于 2012-04-09T01:58:12.893 に答える