qwe*_*zer 4 java inheritance overriding fluent builder
我有一个看起来像这样的类结构:
class Parent {
public Parent(int property) { /* use property */}
}
class Son extends Parent {
public Son(int parentProperty, String sonProperty) {
super(parentProperty);
/* use son property */
}
}
Run Code Online (Sandbox Code Playgroud)
我想为这两个类创建构建器,以便:
class ParentBuilder {
protected int parentProperty;
public ParentBuilder parentProperty(int parentPropertyValue) {
parentPropertyValue = parentPropertyValue;
return this;
}
public Parent build() {
return new Parent(parentProperty);
}
}
class SonBuilder extends ParentBuilder {
private String sonProperty;
public SonBuilder sonProperty(String sonProperty) {
this.sonProperty = sonProperty;
return this;
}
@Override
public Son build() {
return new Son(parentProperty, sonProperty);
}
}
Run Code Online (Sandbox Code Playgroud)
但这会导致以下问题:
SonBuilder sonBuilder = new SonBuilder();
sonBuilder.sonProperty("aString").build(); // this works and creates Son
sonBuilder.sonProperty("aString").parentProperty(1).build(); // this works and creates Parent instead of Son
sonBuilder.parentProperty(1).sonProperty("aString").build(); // this doesn't work
Run Code Online (Sandbox Code Playgroud)
我意识到我在挑剔,这可以通过不返回来解决this(即没有方法链接),但我想知道是否有一个优雅的解决方案.
编辑
似乎"优雅"这个词有点混乱.
"优雅"是指一种允许方法链接而不涉及铸造的解决方案.
第一点
sonBuilder.sonProperty("aString").parentProperty(1).build();
Run Code Online (Sandbox Code Playgroud)
这工作并创建父而不是儿子
预计作为parentProperty()回报a ParentBuilder:
public ParentBuilder parentProperty(int parentPropertyValue) {...
Run Code Online (Sandbox Code Playgroud)
并ParentBuilder.build()创建一个Parent:
public Parent build() {
return new Parent(parentProperty);
}
Run Code Online (Sandbox Code Playgroud)
第二点
sonBuilder.parentProperty(1).sonProperty("aString").build(); // this doesn't work
Run Code Online (Sandbox Code Playgroud)
如第一点所述,parentProperty()返回a ParentBuilder.
而ParentBuilder当然,没有一个sonProperty()方法.
所以它无法编译.
我想知道是否有一个优雅的解决方案.
优雅的解决方案不是SonBuilder 继承,ParentBuilder 而是与ParentBuilder 字段组合.例如 :
class SonBuilder {
private String sonProperty;
private ParentBuilder parentBuilder = new ParentBuilder();
public SonBuilder sonProperty(String sonProperty) {
this.sonProperty = sonProperty;
return this;
}
public SonBuilder parentProperty(int parentPropertyValue) {
parentBuilder.parentProperty(parentPropertyValue);
return this;
}
public Son build() {
return new Son(parentBuilder.parentProperty, sonProperty);
}
}
Run Code Online (Sandbox Code Playgroud)
你可以这样创建Son:
SonBuilder sonBuilder = new SonBuilder();
Son son = sonBuilder.sonProperty("aString").parentProperty(1).build();
Run Code Online (Sandbox Code Playgroud)