2016-04-26 13 views
0

私は方法があります:のJavaのジェネリックメソッドの継承

abstract void method(Holder<?> holder); 

と実装クラスで(独自のタイプとそれぞれ、このような複数のクラスがあるだろう - 工ass、SomeClass2、...):

@Override 
void method(Holder<SomeClass> aHolder) {...} 

これは機能しないので、何が欠けていますか?

コンパイルエラーがあります: は「メソッドはスーパークラスからメソッドをオーバーライドしない」

+0

正確なエラーは何ですか? –

+0

あなたが代わりにメソッドのaddDocsを()をオーバーライドしている() –

+0

申し訳ありませんが、私はそれを修正するよ... は「方法」は、実際に、 をオーバーライドしたものであるが、それは問題ではありませんでした – Dejan

答えて

3

ポイントはvoid method(Holder<?> holder)ニーズの実装は、任意の受け入れることができるようにすることです:Holder<SomeClass>Holder<SomeClass2>Holder<Void>など

メソッドをサブクラスでvoid method(Holder<SomeClass> holder)と宣言しようとすると、ホルダのプロバイダメソッド(たとえばSomeClass value = holder.get())を呼び出すことができますが、パラメータが実際にタイプがHolder<Void>の場合はクラスキャスト例外で失敗します。

このように、タイプシステムによって禁止されています。

abstract class BaseClass<T> { 
    abstract void method(Holder<T> aHolder); 
} 

次にあなたが具体的なクラスを作成することができます:

class SomeClassBaseClass extends BaseClass<SomeClass> { 
    @Override void method(Holder<SomeClass> aHolder) {} 
} 
1

あなたは「より具体的な」実装に上書きしようとしているあなたは、クラスレベルでの型の変数を持っている必要があります

それは "?"を受け入れません、それは "SomeClass"だけを受け入れるので、それは抽象クラスとの "契約"を破るだろう。

あなたのクラスと相互作用する他のクラスの実装を考える場合、それは理解することは簡単です。
"?"は宣言されているので、どんなクラス型でも受け入れることができますが、 "SomeClass"だけを受け入れるとシステムが壊れることになります。

あなたは代わりにクラスレベルで一般的な「T」を使用して、それぞれの実装に使用している型を宣言する必要があります。