質問
ある 不変 クラス:
Scope<Cmp extends Comparable<Cmp>>
public Scope<Cmp> crop(Scope<Cmp> scope) {
...
return new Scope<Cmp>(starts, ends);
}
それは持っています 多くの 同様のメソッドは次のように拡張されます。
Timerange extends Scope<Date>
そして 多くの その他 (これも不変)。
その型のオブジェクトを返してほしいです。例えば:
timerange.crop(scope)
Scope ではなく、Timerange オブジェクトを返す必要があります。
すべてのメソッドをオーバーライドする (またはリフレクションを使用する) 必要がありますか?これを行う別の方法はありますか?
事前にありがとう、エタム。
解決
何らかの工場が必要です。この場合、ファクトリーメソッドは正常に機能します。
public abstract class Scope<E extends Comparable<E>> {
abstract Scope<E> create(E start, E end);
public Scope<E> crop(Scope<E> scope) {
...
return create(starts, ends);
}
}
public TimeRange extends Scope<Date> {
Scope<Date> create(Date start, Date end) {
return new TimeRange (...);
}
}
汎用の「this」パラメータを基本クラスに追加することもできます。
public abstract class Scope<THIS extends Scope<THIS, E>, E extend Comparable<E>> {
abstract THIS create(E start, E end);
public THIS crop(Scope<E> scope) {
...
return create(starts, ends);
}
}
public TimeRange extends Scope<TimeRange,Date> {
TimeRange create(Date start, Date end) {
return new TimeRange (...);
}
}
これにより、クライアント コードに余分な作業が追加されます。
他のヒント
次のことを試してみてください。
class Scope<Cpm extends Comparable<Cpm>, Derived extends Scope<Cpm, Derived>> {
public Derived crop(Scope<Cmp, Derived> scope)
}
TimeRange は次のように定義されます。
class TimeRange extends Scope<Date, Timerange>
など crop
TimeRange オブジェクトを返します。派生クラスが定義されていない場合は、汎用ワイルドカード (Scope<Date, ?>
)
Java には自己型の戻り値がないため、通常はすべてのメソッドを手動でオーバーライドする必要があります。見る 「自分のタイプ」に関する私のブログ いくつかの可能な代替案についての議論のために。
本当に必要ですか Timerange
?それ以上のものを提供しますか Scope<Date>
?そうでない場合は、単に使用してください Scope<Date>
.
もう 1 つの提案は、コンストラクターを使用してオブジェクトをインスタンス化する代わりに、オブジェクトのクローンを作成し、新しいオブジェクトに合わせてフィールドを適切に変更できるかもしれないということです。その理由は、クローンされたオブジェクトが元のオブジェクトと同じタイプであるためです。
Scope<Cmp extends Comparable<Cmp>> implements Cloneable
public Scope<Cmp> crop(Scope<Cmp> scope) {
...
Scope<Cmp> result = (Scope<Cmp>)super.clone();
result.init(starts, ends); // sets the fields for a cloned object
// init() could be private
return result;
}