30

私はスーパークラスFooを持っています。そして、それを拡張するクラス バー。

public class Bar extends Foo

Foo の関数:

protected void saveAll(Collection<?> many)

バーでの機能:

public void saveAll(Collection<MyClass> stuff) {
   super.saveAll(stuff);
}

取得エラー:

 Name clash: The method saveAll(Collection<MyClass>) of type Bar has the same erasure as saveAll(Collection<?>) of type Foo but does not override it.

私は何を間違っていますか?

4

6 に答える 6

23

saveAll互換性のない型でメソッドをオーバーライドしています。おそらく、次のようなことをしたいでしょう:

public class Bar extends Foo<MyClass>

機能Foo<E>

protected void saveAll(Collection<E> many)

およびバーでの機能:

public void saveAll(Collection<MyClass> stuff) {
   super.saveAll(stuff);
}
于 2012-08-13T12:04:35.517 に答える
8

Java の型消去機能により、JVM は、パラメーター化された型 MyClass を持つメソッドなのか、最初に呼び出す必要があるメソッドなのかを認識できません。

可能または適用可能な場合、これを回避するために私が見た中で最も一般的に使用されるパターンは、クラスFooを変更してパラメーター化された型も持つことです。

public class Foo<T> {
    protected void saveAll(Collection<T> many) {}
}

次に、Bar をFoo特定のタイプに単純に実装します。

public class Bar extends Foo<MyClass> {
    public void saveAll(Collection<MyClass> many) {
        super.saveAll(many);
    }
}
于 2012-08-13T12:09:03.813 に答える
5

実行時に、パラメータタイプは。に置き換えられObjectます。したがってsaveAll(Collection<?>)saveAll(Collection<MyClass>)に変換されsaveAll(Collection)ます。これは名前の衝突です。詳細はこちらをご覧ください。

あなたはこれを行うことができます:

public class Foo<T> {
    protected void saveAll(Collection many) {
        // do stuff
    }
}

public class Bar extends Foo<MyClass> {
}
于 2012-08-13T12:19:09.140 に答える
2

コンパイラがバイト コードにコンパイルするとき、Erasure と呼ばれるプロセスが発生します。これにより、コレクションから型情報が削除されます。バイトコードを生成するプロセスの一部として、キャストなどを手動で行うと思います。クラスの一般的な部分 (つまり <..> ) を削除すると、2 つの saveAll メソッドがあることがわかります。エラーは、2 つの save all メソッドが同じ署名になることです。コレクションは、バイトコードに object 型を持っています。

<..> を削除すると、わかりやすくなります。<...> を元に戻すときは、メソッドの名前を検討してください。それらが異なる場合は、コンパイルする必要があります。

また、これが休止状態の問題だとは思わないので、このタグを削除する必要があります。これは、Java の一般的な問題です。

ここでできることは、クラスを入力することです

public class Bar extends Foo<MyClass>

次に、メソッドの型を T にします

public void saveAll(Collection<MyClass> stuff) {
   super.saveAll(stuff);
}

そして、Fooの宣言は次のようになります

public abstract class Bar extends Foo<T> {
    public void saveAll(Collection<T> stuff) {
}
于 2012-08-13T12:10:42.623 に答える
1

異なる署名でメソッドをオーバーライドするだけです。

Joshua Bloch 著『Effective Java Second Edition』で説明されている PECS (Producer - Extends, Consumer - Super) ルールを使用することをお勧めします。

このルールによれば、このように見えるはずです。

Foo クラス:

public class Foo<E>{

protected void saveAll(Collection<? super E> many){....}

protected void getAll(Collection<? extends E> many){....}

}
于 2012-08-13T12:14:21.977 に答える