これは、共分散の問題の側面です。例えば、Covariance and contravarianceを参照してください。そしてDemonstrate covariance and contravariance in Java?。 Javaが優れている場所ではありませんが、いくつかのオプションがあります。
最初にメソッドをオーバーライドすると、より具体的な戻り値の型を宣言することができます。たとえば、MySubClass
の場合、次のように宣言することができます。
@Override
public MySubClass filterOn(String something) {
// ...
}
これで問題は解決しません。この方法でも、MySubClass
オブジェクトに何かを作成して実行する方法が必要です。それがしていることは、クライアントコードをキャストする必要がなくなります。あなたは(result.doSomethingUsingThisInstance()
がprotected
かpublic
であることを提供する)方法フォームdavidxxxの答えの実装を取ることがあります。
@Override
public MySubClass filterOn(String something) {
MySubClass result = new MySubClass();
result.doSomethingUsingThisInstance(this, something);
return result;
}
あなたはすべてのあなたのサブクラスでこのメソッドを複製する必要が悩まさすることができます。実際の仕事がresult.doSomethingUsingThisInstance()
に残っていれば、私はあなたがそれと一緒に暮らすことができると思うべきです。他の考えは正しい実行時の型のオブジェクト生成するためのclone()
にある
:
public class MyClass implements Cloneable {
public MyClass filterOn(String something) {
try {
MyClass result = (MyClass) this.clone();
result.doSomethingUsingThisInstance(this, something);
return result;
} catch (CloneNotSupportedException cnse) {
throw new AssertionError(cnse);
}
}
}
を私はしかし、このアイデアを使用する前によく考えたいです。クローンに含まれたくないデータが含まれている理由の1つで、クローンで作業する前にクリアされていることを確認する必要があります。
public class MySubClass extends MyClass {
@Override
public MySubClass filterOn(String something) {
return (MySubClass) super.filterOn(something);
}
}
を 'filterOn'からの戻り値が'です:あなたは今でもそれだけで(まだ実装、クライアントは心配する必要は何も内側)のキャストを必要とし、サブクラスで特定のサブタイプを返すとそれを組み合わせることができますMyClass'ではなく、 'MySubClass'であるので、例外は十分に有効です。 'result'の型を変更して修正してください。 – Henrik
あなたのフィルタメソッドの 'MyClass result = new MyClass();'に問題があります。あなたはスーパーインスタンスを作成し、最後に返します。サブタイプにキャストすることはできません。 MySubClassのfilterOnメソッドをオーバーライドしたいと思うかもしれません。 – Kent
最も簡単な解決策は 'subClass2'を' MySubClass'イントランスではないのでキャストしないことです。 'MySubClass'のインスタンスが必要な場合は、単純に' filteron'を上書きして、代わりに 'MySubClass'インスタンスを返します。 – n247s