本文将从以下几个方面对子类 builder() 缺少父类属性进行详细阐述:
一、Subclassing with the Builder Pattern
在实现 builder 模式时,我们通常使用一个基础的 builder 类来构建对象。然而,有时候我们需要在继承中使用 builder 模式,此时存在一个问题:子类的 builder 没有继承父类的属性。
例如,假设我们有一个基础的汽车类 Car,它有三个属性:make、model、year。我们想要实现一个 Tesla 类,它是 Car 的子类,然而它有一个额外的属性:battery。
class Car {
private final String make;
private final String model;
private final int year;
// Constructor
private Car(Builder builder) {
this.make = builder.make;
this.model = builder.model;
this.year = builder.year;
}
// Builder class
public static class Builder {
private final String make;
private final String model;
private final int year;
public Builder(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}
public Car build() {
return new Car(this);
}
}
}
class Tesla extends Car {
private final int battery;
private Tesla(TeslaBuilder builder) {
super(builder);
this.battery = builder.battery;
}
public static class TeslaBuilder extends Builder {
private int battery;
public TeslaBuilder(String make, String model, int year) {
super(make, model, year);
}
public TeslaBuilder battery(int battery) {
this.battery = battery;
return this;
}
public Tesla build() {
return new Tesla(this);
}
}
}
可以看到,在子类 Tesla 中,我们需要创建一个 TeslaBuilder 去构建 Tesla 对象。然而,在子类中,TeslaBuilder 并没有继承 Car.Builder 的属性。
二、解决方法
1. 使用父类的静态工厂方法
父类可以提供一个静态的工厂方法,用于从子类的 builder 中构建父类实例。这种方法可以将父类的属性添加到子类 builder 中,并在子类的 build() 方法中调用父类的 build() 方法。
class TeslaBuilder extends Builder {
private int battery;
public static TeslaBuilder newBuilder() {
return new TeslaBuilder();
}
private TeslaBuilder() {
super("Tesla", "Model S", 2019);
}
public TeslaBuilder battery(int battery) {
this.battery = battery;
return this;
}
@Override
public Car build() {
return new Tesla(this);
}
}
class Tesla extends Car {
private final int battery;
private Tesla(TeslaBuilder builder) {
super(builder);
this.battery = builder.battery;
}
// Static factory method
public static TeslaBuilder newBuilder() {
return TeslaBuilder.newBuilder();
}
}
在上面的代码中,TeslaBuilder 继承自 Car.Builder。我们使用父类 Car 的静态工厂方法来创建一个名为 “Tesla” 的实例,同时,我们也可以在子类 TeslaBuilder 中添加子类的属性 “battery”。
此外,在 TeslaBuilder 的 build() 方法中,我们调用了父类 Car 的 build() 方法来创建 Tesla 对象。
2. 通过抽象方法继承
另一种解决方法是,使用抽象方法来实现属性的继承。
abstract class Car {
protected final String make;
protected final String model;
protected final int year;
protected Car(CarBuilder builder) {
this.make = builder.make;
this.model = builder.model;
this.year = builder.year;
}
public static abstract class CarBuilder<e b="" car,="" carbuilder> {
protected String make;
protected String model;
protected int year;
public B make(String make) {
this.make = make;
return self();
}
public B model(String model) {
this.model = model;
return self();
}
public B year(int year) {
this.year = year;
return self();
}
public abstract E build();
protected abstract B self();
}
}
class Tesla extends Car {
private final int battery;
private Tesla(TeslaBuilder builder) {
super(builder);
this.battery = builder.battery;
}
public static class TeslaBuilder extends CarBuilder {
private int battery;
public TeslaBuilder battery(int battery) {
this.battery = battery;
return self();
}
@Override
public Tesla build() {
return new Tesla(this);
}
@Override
protected TeslaBuilder self() {
return this;
}
}
}
在上面的代码中,我们使用了一个抽象方法 self() 来返回 builder 对象。通过让子类的 builder 实现该方法,我们可以保证属性的继承问题。在 TeslaBuilder 的 build() 方法中,我们返回了 Tesla 对象。
三、小结
子类 builder() 缺少父类属性是 builder 模式中的一种常见问题。本文介绍了两种方法来解决这个问题:静态工厂方法和抽象方法继承。在实现 builder 模式时,选择哪种方法需要根据实际情况来决定。
原创文章,作者:NNSGS,如若转载,请注明出处:https://www.506064.com/n/373931.html