我在父类和子类中都有构建器。父级具有抽象构建器和扩展抽象构建器的具体构建器。子项具有一个抽象构建器,用于扩展父抽象构建器和扩展子抽象构建器的具体构建器。这样做的原因是父级的setter返回当前的Builder类。我有方法返回类自己的抽象构建器类型,我想将其称为父抽象类型(在其上调用父方法)。我可以上班的只有ParentBuilder<? extends ParentBuilder<?>>
,但由于通配符,这看起来并不好。这是一个可以更好地解释它的例子。
我想在主要代码中做些什么:
ParentBuilder<? extends ParentBuilder<?> builder; // How to do this?
if (something) {
builder = Child.doSomething();
}
else {
builder = new Parent.builder();
}
Parent p = builder.setThing1("foo").build();
在Parent.java中
public class Parent {
private final String thing1;
protected <B extends ParentBuilder<B>> Parent(final B builder) {
this.thing1 = builder.thing1;
}
public String getThing1() {
return this.thing1;
}
protected abstract static class ParentBuilder<B extends ParentBuilder<B>> {
protected final Class<B> builderClass;
protected String thing1;
protected ParentBuilder(final Class<B> builderClass) {
this.builderClass = builderClass;
}
public B setThing1(final String thing1) {
this.thing1 = thing1;
return builderClass.cast(this);
}
public abstract Parent build();
}
public static class Builder extends ParentBuilder<Builder> {
public Builder() {
super(Builder.class);
}
@Override
public Parent build() {
return new Parent(this);
}
}
}
在Child.java中
public class Child extends Parent {
private final String thing2;
protected <B extends ChildBuilder<B>> Child(final B builder) {
super(builder);
this.thing2 = builder.thing2;
}
public String getThing2() {
return this.thing2;
}
public static Builder doThings(/*...*/) {
//...
return new Child.Builder();
}
protected abstract static class ChildBuilder<B extends ParentBuilder<B>> extends ParentBuilder<B> {
protected String thing2;
protected ChildBuilder(final Class<B> builderClass) {
super(builderClass);
}
public B setThing2(final String thing2) {
this.thing2 = thing2;
return builderClass.cast(this);
}
}
public static class Builder extends ChildBuilder<Builder> {
public Builder() {
super(Builder.class);
}
@Override
public Child build() {
return new Child(this);
}
}
}
在第一部分中,我将构建器声明为父抽象构建器类型,但我不确定键入该对象的正确方法。通配符似乎不对。我想到的一个选项是在抽象构建器上面创建一个接口,然后我可以使用该类型。但是拥有界面似乎很麻烦 - &gt;抽象类 - &gt;父类和每个子类中的具体类。有没有人有任何其他建议?谢谢。
答案 0 :(得分:1)
以下是使用您的设置的工作代码:
Parent.ParentBuilder<?> builder;
if ( something ) {
builder = new Child.Builder();
}
else {
builder = new Parent.Builder();
}
Parent p = builder.setThing1("foo").build();
现在,如果您希望builder.build()
在没有强制转换的情况下返回Child
,则需要更改现有的构建器泛型类型声明。