我基于这个答案实现了模式,我有以下asbtract配置:
public abstract class AbstractConfig {
public static abstract class Builder<B extends Builder<B>> {
private int calories = 0;
public Builder() {
}
public B setCalories(int calories) {
this.calories = calories;
return (B) this;
}
public abstract AbstractConfig build();
}
private int calories = 0;
protected AbstractConfig(final Builder builder) {
calories = builder.calories;
}
}
我有以下具体配置:
public class DialogConfig extends AbstractConfig {
public static class DialogConfigBuilder<B extends DialogConfigBuilder<B>> extends Builder<B> {
private double width;
private double height;
public DialogConfigBuilder() {
//does nothing.
}
public B setWidth(final double value) {
width = value;
return (B) this;
}
public B setHeight(final double value) {
height = value;
return (B) this;
}
public DialogConfig build() {
return new DialogConfig(this);
}
}
private final double width;
private final double height;
protected DialogConfig(final DialogConfigBuilder builder) {
super(builder);
width = builder.width;
height = builder.height;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
}
这就是我使用它的方式
DialogConfig config = new DialogConfig.DialogConfigBuilder()
.setWidth(0)
.setCalories(0)
.setHeight(0) //X LINE
.build();
在X行我得到-找不到符号方法setHeight。我的错误是什么?
编辑 - 我将有一个扩展的诊断配置,必须扩展对话框配置等。我的意思是会有其他子类。
我发现了我的错误。这是我如何使用DialogConfigBuilder的
DialogConfig config = new DialogConfig.DialogConfigBuilder()
.setWidth(0)
.setCalories(0)
.setHeight(0) //X LINE
.build();
这就是我应该如何使用DialogConfigBuilder
DialogConfig config = new DialogConfig.DialogConfigBuilder<>()
.setWidth(0)
.setCalories(0)
.setHeight(0) //X LINE
.build();
请注意<code>
您首先将<code>setCalories()
public Builder<B> setCalories(int calories) {
this.calories = calories;
return this;
}
去掉强制转换和警告。现在仔细看看这个。您返回一个Builder。这段代码不知道未来的子类。它只返回该基础构建器的一个实例。
因此,当您具有该链接调用时:
.setHeight(0) .build();
这将返回该基础构建器。然后调用 build()
- 这将构建一个抽象配置。但是您希望将其分配给更具体的对话配置。因此,错误。
一个(丑陋的)解决方法:
DialogConfig.DialogConfigBuilder<?> builder = new DialogConfig.DialogConfigBuilder<>().setHeight(0);
builder.setCalories(0);
...config = builder.build();
还有一个解决方案——再次修改< code > setcales():
@SuppressWarnings("unchecked")
public <T extends B> T setCalories(int calories) {
this.calories = calories;
return (T) this;
}
修复编译错误;并且还允许链接<code>setCalories()
记录在案的是“完整”解决方案,包括消除原始类型和其他警告的所有自适应:
abstract class AbstractConfig {
public static abstract class Builder<B extends Builder<B>> {
private int calories = 0;
@SuppressWarnings("unchecked")
public <T extends B> T setCalories(int calories) {
this.calories = calories;
return (T) this;
}
public abstract AbstractConfig build();
}
private int calories = 0;
public int getCalories() { return calories; }
protected <B extends Builder<B>> AbstractConfig(final Builder<B> builder) {
calories = builder.calories;
}
}
final class DialogConfig extends AbstractConfig {
public static class DialogConfigBuilder<B extends DialogConfigBuilder<B>> extends Builder<B> {
private double width;
private double height;
public DialogConfigBuilder<B> setWidth(final double value) {
width = value;
return this;
}
public DialogConfigBuilder<B> setHeight(final double value) {
height = value;
return this;
}
public DialogConfig build() {
return new DialogConfig(this);
}
}
private final double width;
private final double height;
protected <B extends DialogConfigBuilder<B>> DialogConfig(final DialogConfigBuilder<B> builder) {
super(builder);
width = builder.width;
height = builder.height;
}
public double getWidth() { return width; }
public double getHeight() { return height; }
}
public class Builders {
public static void main(String[] args) {
DialogConfig config = new DialogConfig.DialogConfigBuilder<>().setHeight(0).setCalories(0).build();
System.out.println(config);
}
}
问题内容: 我想将一个Web服务URL请求表示为一个对象,并发现在继承层次结构中可能有很多通用参数。一个请求可以有很多参数,一些是必选参数,而其他是可选参数,我相信Bloch的Builder模式是一个不错的选择,它可以使用流畅的接口模拟命名参数。 具体来说,我正在设计Google Maps网络服务API,该API具有常规的网络服务请求 和是必填参数,也是必填参数。还有一个可选参数。 每个服务都有其
问题内容: 我有三节课: 现在在我的主要职能中,我做这样的事情: 但这会产生2个编译时错误: 无法将A转换为fileHandler 无法将B转换为fileHandler 如果基类不是泛型的,那么我如何摆脱这些错误呢? 更新: 我的班级层次结构是: 调用函数的C类或 调用函数的D类。 C和D都从抽象类E派生。 现在,我应该如何在C和D以及E中定义这些功能: 我给出了以下内容: E: C: D: C,
问题内容: 我正在编写一个流畅的API,以配置和实例化一系列“消息”对象。我有消息类型的层次结构。 为了在使用Fluent API时能够访问子类的方法,我使用了泛型来对子类进行参数化,并使所有的fluent方法(以“ with”开头)都返回泛型类型。注意,我省略了流利方法的大部分内容。其中进行了许多配置。 具体的子类类似地重新定义泛型。 该代码有效,即,我可以实例化任何类并使用所有流利的方法: 以
问题内容: 我的对象层次结构随着继承树的加深而增加了复杂性。这些都不是抽象的,因此,它们的所有实例都或多或少地达到了目的。 由于参数数量很多,我想使用“构建器模式”来设置属性,而不是对多个构造函数进行编码。由于我需要适应所有排列,因此继承树中的叶类将具有伸缩构造函数。 当我在设计过程中遇到一些问题时,我已经浏览了这里的答案。首先,让我给您一个简单的,简短的示例来说明问题。 现在我们有一些代码可以继
Java Lombok库:继承的生成器注释问题 创建子类的实例时,父类属性在生成器注释中不可见。 以下失败: 然而,下面的说法是正确的: 似乎这个问题已经存在很长时间了,不知道最新版本是否有任何修正。
我有一个Spring Boot(kotlin)项目,我使用springdoc openapi生成openapi 3规范。我的数据模型如下所示: 还有一个简单的控制器,如下所示: 生成的yaml为: 这里的问题是我的控制器可以返回或,这在返回类型中指定。我期望生成的模式是: 有没有办法做到这一点?