4

このコードの何が問題になっていますか?

public interface FileProccessor {
    public <RT> RT setHeader(RT header);
}

public class AProcessor implements FileProccessor {

    @Override
    public Header setHeader(Header header) {
        return null;
    }
}

コンパイラが不平を言っています:タイプ AProcessor のメソッド setHeader(Header) は、スーパータイプ メソッドをオーバーライドまたは実装する必要があります

編集: ありがとう。タイプの異なる複数のメソッドが必要だったので、混乱しました。今、クラスレベルで必要なだけパラメータ化された型を追加できることに気付きました。のようにFileProcessor<T, F, M>

4

5 に答える 5

4

インターフェイス宣言は、インターフェイスのすべての実装がこのシグネチャを持つジェネリック メソッドを提供することを指定します。

public <RT> RT setHeader(RT header);

つまり、呼び出し元は任意の型のオブジェクトを渡し、まったく同じ型のオブジェクトを返すことができます。

一方、実装宣言では、ユーザーを単一のタイプ、つまりHeader. そのため、コンパイラはオーバーライドできないと不平を言っています。

インターフェイスがジェネリックであり、それを実装する型が次のようにジェネリック インスタンスを実装している場合、このトリックは機能します。

public interface FileProccessor<T> {
    public T setHeader(T header);
}

public class AProcessor implements FileProccessor<Header> {
}
于 2012-09-28T10:05:45.967 に答える
3

私はあなたがこれをしたいと思う:

public interface FileProccessor<RT, RX> {
    public RT setHeader(RT header);
    public RX setFooter(RX footer);
}

public class AProcessor implements FileProccessor<Header, Footer> {

    @Override
    public Header setHeader(Header header) {
        return null;
    }

    @Override
    public Footer setFooter(Footer footer) {
        return null;
    }
}
于 2012-09-28T10:03:44.370 に答える
1

次のようにインターフェイスを定義してみてください。

public interface FileProccessor<RT> {
    public RT setHeader(RT header);
}

そして、次のように実装します。

public class AProcessor implements FileProccessor<Header> {
    @Override
    public Header setHeader(Header header) {
        return null;
    }
}
于 2012-09-28T10:04:10.190 に答える
0

この方法でメソッドをオーバーライドすることはできません。への入力としてAProcessor受け入れるすべてのものを受け入れることができなければなりません。次のコードを検討してください。FileProcessorsetHeader

FileProcessor f = new AProcessor();
String s =  f.setHeader("Bah");

このコードは、どの具象クラスが使用されていても機能するはずですが、あなたのAProcessor. したがって、型チェッカーがそれを拒否するのは理にかなっています。

次のようなものが機能します (FileProcessor インターフェースが RT でパラメーター化されているため):

public interface FileProccessor<RT> {
    public RT setHeader(RT header);
}

public class AProcessor implements FileProccessor<Header> {

    @Override
    public Header setHeader(Header header) {
        return null;
    }
}

クラスのユーザーは、次のように記述する必要があります。

FileProcessor<Header> f = new AProcessor();

への引数は...setHeader型でなければなりません。Header

于 2012-09-28T10:06:01.193 に答える
0

JLS # 8.4.2。メソッド署名

次のいずれかの場合、メソッド m1 の署名は、メソッド m2 の署名のサブ署名です。

  • m2 が m1 と同じ署名を持っている、または

  • m1 の署名は、m2 の署名の消去 (§4.6) と同じです。

あなたの場合erasureは異なります。一度は持っていて、実装クラスでは持っていません。

生の型は以下のジェネリックメソッドをオーバーライドできるため、あなたのケースでは機能します。

    @Override
    public Object setHeader(Object header) {
        return null;
    }

また、以下のように宣言を変更すると

 public interface FileProccessor<T> {
    public T setHeader(T header);
 }

FileProccessor<T>拡張中に子クラスで渡された Type に基づいてメソッドをオーバーライドできます

public class AProcessor implements FileProccessor<Header> {
    @Override
    public Header setHeader(Header header) {
        return null;
    }
}
于 2012-09-28T10:20:53.787 に答える