使用Builder模式扩展类

我正在尝试将类a扩展为aX。 所以,我也扩展了aBuilder。 但是,虽然我能够使用以下方法创建类a的对象:

aBuilder f = new aBuilder(); f.bi = i; f.bs = s; a atry = f.withI(i).withS(s).build(); 

这同样适用于aX。 当我尝试这样做时:

 aXBuilder fb = new aXBuilder(); aX aXtry = fb.withI(i).withS(s).withB(b).build(); 

我收到一个错误(对于a.aBuilder类型,未定义withB(Boolean)方法)。 我是否应该为aX重写所有内容,而不是简单地添加新内容? 我不想这样做,因为这会导致我的代码中出现大量重复。 a和aX类如下:

 class a { protected String s; protected int i; public void getdata() { System.out.println(this.s); System.out.println(this.i); } protected a(aBuilder fb) { this.s = fb.bs; this.i = fb.bi; } public static class aBuilder { public aBuilder() { } protected String bs; protected int bi; public aBuilder withS(String s) { this.bs = s; return this; } public aBuilder withI(Integer i) { this.bi = i; return this; } public a build() { return new a(this); } } 

}

class aX扩展了一个{

 protected Boolean b; public void getData() { System.out.println(this.s); System.out.println(this.i); System.out.println(this.b); } protected aX(aXBuilder axb) { super(axb); this.b = axb.bb; } public static class aXBuilder extends aBuilder { protected Boolean bb; public aXBuilder() { } public aXBuilder withB(Boolean b) { this.bb = b; return this; }; public aX build() { return new aX(this); } } 

}

您可以使用generics来解决问题,尽管它确实需要创建抽象超类。 潜伏在这个网站上告诉我,从一个具体的类inheritance被广泛认为是邪恶的。

 public abstract class AbstractA { protected String s; protected int i; protected AbstractA() { } protected abstract static class ABuilder> { protected T object; protected B thisObject; protected abstract T getObject(); //Each concrete implementing subclass overrides this so that T becomes an object of the concrete subclass protected abstract B thisObject(); //Each concrete implementing subclass builder overrides this for the same reason, but for B for the builder protected ABuilder() { object = getObject(); thisObject = thisObject(); } public B withS(String s) { object.s = s; return thisObject; } public B withI(int i) { object.i = i; return thisObject; } public T build() { return object; } } } 

一旦将抽象类放在一起,就可以根据需要多次扩展它,覆盖构建器中的抽象方法以返回所需对象的类型。

 public final class ConcreteA extends AbstractA { private String foo; protected ConcreteA() { } public static final class Builder extends AbstractA.ABuilder { @Override protected ConcreteA getObject() { return new ConcreteA(); } @Override protected Builder thisObject() { return this; } public Builder() { } public Builder withFoo(String foo) { object.foo = foo; return this; } } } 

然后…… ConcreteA baz = new ConcreteA.Builder().withFoo("foo").withS("bar").withI(0).build();

withS(s)返回aBuilderaBuilder没有方法withB

需要重构。 在子类中覆盖withS等以返回正确的类型。

(你通常不显式实例化构建器,只是静态地引用它们btw,并且作为类名是坏的)