有一个不可变的类:
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)
应该返回Timerange对象,而不是Scope。
我是否必须覆盖每个方法(或使用反射)? 还有另一种方法吗?
提前致谢, 艾格。
答案 0 :(得分:4)
你需要某种工厂。在这种情况下,工厂方法可以正常工作。
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 (...);
}
}
这确实为客户端代码添加了额外的工作。
答案 1 :(得分:2)
Java没有自我类型返回,因此您通常需要手动覆盖每个方法。有关可能的替代方案的讨论,请参见my blog on "self types"。
答案 2 :(得分:2)
您可以尝试以下方法:
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, ?>
)
答案 3 :(得分:0)
你真的需要Timerange
吗?它提供的不仅仅是Scope<Date>
吗?如果没有,那么只需使用Scope<Date>
。
另一个建议是,可能不是使用构造函数实例化它,而是可以克隆该对象,然后为新对象适当地修改字段。原因是克隆的对象与原始对象的类型相同。
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;
}