我在读有效的 Java 版本 3。在第 2 章第 14 页中,作者讨论了构建器模式并呈现了以下代码:
public abstract class Pizza {
public enum Topping { HAM, MUSHROOM, ONION, PEPPER, SAUSAGE }
final Set<Topping> toppings;
abstract static class Builder<T extends Builder<T>> {
EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
public T addTopping(Topping topping) {
toppings.add(Objects.requireNonNull(topping));
return self();
}
abstract Pizza build();
// Subclasses must override this method to return "this"
protected abstract T self();
}
Pizza(Builder<?> builder) {
toppings = builder.toppings.clone(); // See Item 50
}
}
上述抽象类的实现:
public class NyPizza extends Pizza {
public enum Size { SMALL, MEDIUM, LARGE }
private final Size size;
public static class Builder extends Pizza.Builder<Builder> {
private final Size size;
public Builder(Size size) {
this.size = Objects.requireNonNull(size);
}
@Override public NyPizza build() {
return new NyPizza(this);
}
@Override protected Builder self() { return this; }
}
private NyPizza(Builder builder) {
super(builder);
size = builder.size;
}
}
我们可以使用这样的代码:
NyPizza pizza = new NyPizza.Builder(SMALL)
.addTopping(SAUSAGE).addTopping(ONION).build();
书中引用:
注意Pizza.Builder
is a 泛型 with 递归类型
范围。这与抽象 self 方法一起允许方法
链接可以在子类中正常工作,而不需要强制转换。
现在我的问题是什么力量/价值<T extends Builder<T>>
添加到Pizza
类以及它有何不同<T extends Builder>
?如果你要解释的话<T extends Builder<T>>
对一个五岁的孩子用简单的英语你会怎么解释?
我无法弄清楚超类中抽象 self 方法的用途?
因为评论区所以我添加了这部分
想象一下我已经像这样更改了上面的代码(这不会是仅用于说明目的的最佳示例):
我改变了NyPizza.Builder
通用:
public class NyPizza extends Pizza {
public enum Size { SMALL, MEDIUM, LARGE }
private final Size size;
public static class Builder<T> extends Pizza.Builder<Builder<T>> {
private final Size size;
public Builder(Size size) {
this.size = Objects.requireNonNull(size);
}
@Override public NyPizza build() {
return new NyPizza(this);
}
@Override protected Builder self() { return this; }
}
private NyPizza(Builder builder) {
super(builder);
size = builder.size;
}
}
and the Pizza
像这样的类:
public abstract class Pizza {
public enum Topping { HAM, MUSHROOM, ONION, PEPPER, SAUSAGE }
final Set<Topping> toppings;
abstract static class Builder<T extends Builder> {
T obj;
EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
public T addTopping(Topping topping) {
toppings.add(Objects.requireNonNull(topping));
return self();
}
public T builder(){
return obj;
}
abstract Pizza build();
// Subclasses must override this method to return "this"
protected abstract T self();
}
Pizza(Builder<?> builder) {
toppings = builder.toppings.clone(); // See Item 50
}
}
并像这样使用上面的类:
NyPizza.Builder<String> test = new NyPizza.Builder<String>(SMALL).builder();
现在因为我没有定义class Builder<T extends Builder>
以这种形式:class Builder<T extends Builder<T>>
the builder
方法中的Pizza
类不应该能够检测到 T 的类型NyPizza.Builder<String>
但它可以。这怎么可能?如何将其更改为需要铸造?