Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 生成器模式和扩展自身的泛型类型_Java_Generics_Design Patterns - Fatal编程技术网

Java 生成器模式和扩展自身的泛型类型

Java 生成器模式和扩展自身的泛型类型,java,generics,design-patterns,Java,Generics,Design Patterns,我试图用继承实现构建器模式,并发现了以下内容 这是B类: 公共类B扩展了{ 公共静态抽象类生成器 扩展A.Builder{ @凌驾 公共摘要:T getThis(); 公共建筑商b方法(){ //实施 归还这个; } 公共B build(){ 返回新的B(本); } } 私人乙(建筑商){ 超级建筑商; //B实地作业 } } 现在我想让C类也是可扩展的。我就是这样做的: 公共类C扩展B{ ... 公共静态类生成器扩展了B.Builder{ .... } } 因此,在C中,我们有一个可以在D

我试图用继承实现构建器模式,并发现了以下内容

这是
B
类:

公共类B扩展了{
公共静态抽象类生成器
扩展A.Builder{
@凌驾
公共摘要:T getThis();
公共建筑商b方法(){
//实施
归还这个;
}
公共B build(){
返回新的B(本);
}
}
私人乙(建筑商){
超级建筑商;
//B实地作业
}
}
现在我想让C类也是可扩展的。我就是这样做的:

公共类C扩展B{
...
公共静态类生成器扩展了B.Builder{
....
}
}
因此,在
C
中,我们有一个可以在
D
中扩展的生成器。我的问题是创建C.Builder实例的正确方法是什么。我的意思是,我应该在它的泛型中设置什么:

C.Builder<WHAT HERE> builder = new C.Builder<>();
C.Builder=new C.Builder();

由于
C.Builder
的参数
T
必须是扩展
C.Builder
的对象,因此必须创建另一个扩展
C.Builder
的类,因为它是参数化的,所以不能使用
C.Builder
本身

因此,继承的构建器的解决方案是创建两个构建器,一个是通用的、可扩展的、受保护的和抽象的,另一个是公共的、最终的、非通用的,用于实际的构建

下面是显示以下内容的示例类:

public class Person {
  private final String name;

  public Person(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  protected static abstract class ExtensiblePersonBuilder<S, T extends Person> {
    protected String name;

    public S name(String name) {
      this.name = name;
      return self();
    }

    public abstract S self();
    public abstract T build();
  }

  public static final class PersonBuilder extends ExtensiblePersonBuilder<PersonBuilder, Person> {
    @Override
    public PersonBuilder self() {
      return this;
    }

    @Override
    public Person build() {
      return new Person(name);
    }
  }
}
或:


B
看起来怎么样?这只是一个模糊的想法,但我会将
C
设计为可扩展的(因此具有与
B
相同的抽象生成器)或不可扩展的(因此具有创建
C
实例的具体生成器)。混合使用具体的类和继承是有可能的,但总是有问题的,而且可能是令人讨厌的。生成器是一个允许您构建复杂事物的类。比如:var builder=newsqlbuilder();建造商。可添加表格(“员工”);建筑商加入(“工资”、“身份证”、“身份证员工”);builder.addWhere(SQLWhere.equals(“id”,6));字符串查询=builder.build();构建器模式中不需要链接调用的功能,但可以使其更具表现力。通过静态导入,它可能看起来像:select(“Employees”).innerJoin(“salarys”,eq(“id”,“id_Employees”).where(eq(“id”,6)).build()
  public class Employee extends Person {
    private int number;

    public Employee(String name, int number) {
      super(name);

      this.number = number;
    }

    protected static abstract class ExtensibleEmployeeBuilder<S, T extends Employee> extends ExtensiblePersonBuilder<S, T> {
      protected int number;

      public S number(int number) {
        this.number = number;
        return self();
      }
    }

    public static final class EmployeeBuilder extends ExtensibleEmployeeBuilder<EmployeeBuilder, Employee> {

      @Override
      public EmployeeBuilder self() {
        return this;
      }

      @Override
      public Employee build() {
        return new Employee(name, number);
      }
    }
  }
public class Manager extends Employee {
  private String teamName;

  public Manager(String name, int number, String teamName) {
    super(name, number);

    this.teamName = teamName;
  }

  protected static abstract class ExtensibleManagerBuilder<S, T extends Manager> extends ExtensibleEmployeeBuilder<S, T> {
    protected String teamName;

    public S teamName(String teamName) {
      this.teamName = teamName;
      return self();
    }
  }

  public static final class ManagerBuilder extends ExtensibleManagerBuilder<ManagerBuilder, Manager> {
    @Override
    public ManagerBuilder self() {
      return this;
    }

    @Override
    public Manager build() {
      return new Manager(name, number, teamName);
    }
  }
}
Person p = new PersonBuilder().name("John").build();
Manager m = new ManagerBuilder().name("Jeff").teamName("X").number(2).build();