我有以下代码实现抽象生成器(如有效的Java书中所述):
interface I {
I ret();
}
abstract class A implements I {
private String s = "";
A(Builder b) {
s = b.s;
}
@Override
public I ret() {
String s = "some new string from calc.";
//HERE I NEED TO CONSTRUCT class B
//THIS IS PROBLEMATIC LINE BELOW <<<<--------------------------------------
return new Builder<>().withString(s).build();
}
static abstract class Builder<T extends Builder<T>> {
String s = "";
T withString(String s) {
this.s = s;
return self();
}
protected abstract A build();
//simulated self-type idiom
protected abstract T self();
}
}
class B extends A {
private B(A.Builder b) {
super(b);
}
static class Builder extends A.Builder<Builder> {
@Override
protected B build() {
return new B(this);
}
@Override
protected Builder self() {
return this;
}
}
}
这是一个小用例
public static void main(String[] args) {
I b = new B.Builder().withString("bclass").build();
I b2 = b.ret(); //<---- this one should construct new immutable B
}
我想做的是-通过类ret()
中的A
方法,我想构造一个不了解父类型的不可变对象-因此在我的示例中,它将是新类{ {1}}具有新的内部字符串。
问题是类B
不知道类A
,因为B
是它的父类。
在不求助于泛型的情况下,这样的事情是否可能?
如果我使用可变类,它将像B
一样简单。
更新
this.s = newS;
答案 0 :(得分:4)
您需要在A
中提供一种抽象方法,以构建Builder
的合适实例:
abstract Builder<A> toBuilder();
然后在具体的子类中实现它,并调用:
return toBuilder().withString(s).build();