首先,我对 Java 比较陌生,所以我所问的可能是微不足道的,但我在这里或其他地方找不到答案。
为简单起见,假设我有以下类层次结构:
class Shape {
protected Shape(double x, double y) {...}
}
class Circle extends Shape {
public Circle(double radius) {...}
}
class Rectangle extends Shape {
public Rectangle(double edge) {...}
}
我想为每个形状使用构建器模式。因此,我为它们中的每一个都添加了 Builders:
class Shape {
protected static abstract class BuilderBase<T extends BuilderBase<T, S>, S extends Shape> {
public T setLocation(double x, double y) {
// ...
return (T)this; // ? - is there a way to avoid this casting?
}
public abstract S build();
}
protected Shape(/*...*/) {/*...*/}
}
class Circle extends Shape {
public static class Builder extends BuilderBase<Builder, Circle> {
public Builder setRadius(double radius) {
//...
return this;
}
@Override
public Circle build() { return new Circle(/*...*/); }
}
private Circle(/*...*/) {/*...*/}
}
class Rectangle extends Shape {
public static class Builder extends BuilderBase<Builder, Rectangle> {
public Builder setRadius(double radius) {
//...
return this;
}
@Override
public Rectangle build() {
return new Rectangle(/*...*/);
}
}
public Rectangle(/*...*/) {/*...*/}
}
编辑: 这里使用泛型是为了允许以任何顺序使用 Builder 方法。例如,为了允许以下调用:
new Circle.Builder()
.setLocation(0, 0)
.setRadius(10)
.build();
我的问题在于这个铸造:
public T setLocation(double x, double y) {
// ...
return (T)this; // ? - is there a way to avoid this casting?
}
我正在努力寻找一种方法来避免这种铸造。到目前为止,我发现的唯一方法是向 BaseBuilder 方法添加另一个抽象方法:
protected static abstract class BuilderBase<T extends BuilderBase<T, S>, S extends Shape> {
protected abstract T getBuilder();
public T setLocation(double x, double y) {
// ...
return getBuilder();
}
//...
}
所以每个派生的构建器都必须实现它:
@Override
protected Circle getBuilder() {
return this;
}
在我看来这有点矫枉过正,但我不想收到编译警告。
问题:有没有更优雅的方法来避免铸造?