Java 具有可变构造函数参数数的子类的静态工厂方法

Java 具有可变构造函数参数数的子类的静态工厂方法,java,inheritance,subclass,Java,Inheritance,Subclass,这更像是一个风格问题,我不确定我的问题的解决方案是“最干净的” 实施细节并不重要,我想做的是: 我有一个抽象类,它被几个本质上非常相似的子类扩展。我想通过使这些类只能通过超类中的静态方法来实例化,从而对客户机隐藏这些类,该方法返回对子类实例的超类引用(具体类由方法参数确定)。 到目前为止还不错,我相信这是一件很平常的事情 现在,我所说的这些子类可以分为两个组,一个组的成员需要两个参数才能被构造,另一个组的成员需要一个额外的参数 现在我的问题是:如何让客户端通过上面提到的静态方法获得这两种类型。我

这更像是一个风格问题,我不确定我的问题的解决方案是“最干净的”

实施细节并不重要,我想做的是:

我有一个抽象类,它被几个本质上非常相似的子类扩展。我想通过使这些类只能通过超类中的静态方法来实例化,从而对客户机隐藏这些类,该方法返回对子类实例的超类引用(具体类由方法参数确定)。 到目前为止还不错,我相信这是一件很平常的事情

现在,我所说的这些子类可以分为两个组,一个组的成员需要两个参数才能被构造,另一个组的成员需要一个额外的参数

现在我的问题是:如何让客户端通过上面提到的静态方法获得这两种类型。我是否提供了两个具有不同参数列表的静态方法?我是否强制客户端在第一个组不需要的第三个可选参数上传递零?这个有设计模式吗?(我考虑过有效Java中的构建器模式,但据我所知,构建器模式通常在不同的上下文中使用)。还是修改继承层次结构

任何答案都将不胜感激

编辑:

我认为我的问题目前有点复杂,所有这些都添加了一点代码以使其更清楚:

abstract class SuperClass{

    public static SuperClass getSuperClass(String type, int i1, int i2, int optional) {

        /*
         *'type' alone determines which concrete subclass is instanciated
         *'optional' is only needed for the construction for some of those 'types'
         *so the implementation of this method might look like this:
         */

        switch(type) {
            case "1":
                return new Subclass1(i1, i2);
                break;
            case "2":
                return new Subclass2(i1, i2, optional);
                break;

        /*
         *So the problem is this: always passing 'optional' is weird if it 
         *is then simply discarded in some cases.
         *Overloading is weird as well because I don't want to split up 
         *the switch statement or check for exceptions in every case 
         *(when optional is/is not declared for types where it 
         *shouldn't/should be)
         */
    }

}

您可以传递一个配置字符串或配置对象(例如属性),该对象的详细信息与实现所需的内容相同。它可以是1个或100个参数。但是,对于调用方,只传递了一个包装参数。

这取决于。听起来您的超类静态方法返回了一个
超类
实例。如果是这样,您可以根据附加参数返回不同的子类实例

考虑一个抽象类
Vehicle
。现在有两个抽象类
SingleDeckVehicle
MultiDeckVehicle
扩展
Vehicle
,前两个参数是车轮数和座椅数,另外一个参数是车辆的甲板数。然后,甲板的数量将非常重要,实际上,如果您的客户想要一个
单层车辆
实例,他/她将传递一个
1
作为第三个参数

但是,您也可以创建另一个静态方法。假设您已经定义了一个静态方法
Vehicle.getVehicle(int-wheelNo、int-seatNo、int-deckNo)
。您还可以定义另一个:
Vehicle.getSingleDeckVehicle(int-wheelNo,int-seatNo)
返回
Vehicle.getVehicle(wheelNo,seatNo,1)

类似的例子是BorderFactory: . 我希望我正确理解了您的问题…

您有两个选择:

选项1

超级类中的
静态工厂方法可以使用var args实现:

public static SuperClass newInstace(int...parameters) {
     SuperClass superClass = null;
     if(parameters.length == 2) {
          if(parameters[1]>=5) {//instantiate a subclass based on a value
             super = new SubClass1(parameters[0],parameters[1]);
          } else {
             super = new SubClass2(parameters[0],parameters[1]);
          }

     } else if(parameters.length == 3) {
           if(parameters[2]>=5) {
             super = new SubClass3(parameters[0],parameters[1],parameters[2]);
          } else {
             super = new SubClass4(parameters[0],parameters[1],parameters[2]);
          }
     } else {
          throw new IllegalArgumentException("Invalid number of parameters passed to newInstance. Expected number of parameters [min = 2, max = 3]")
     }

     return superClass;
}
选项2

或者,您可以重载
newInstance
方法,让其中一个接受2个参数,另一个接受3个参数

两种方法各有利弊,如下所述:

  • 当您期望在现有子类中引入新字段的频率或期望在现有子类中引入更多字段的新子类的频率极低时,方法1是一个更好的选择
  • 当您期望在现有子类中引入新字段的频率或您期望在现有子类中引入更多字段的新子类的频率相对较高时,方法2是一个更好的选择,因为方法1将导致非常大的方法体

  • 这听起来像是使用Spring或Guice进行依赖项注入的好例子。
    一个组,其成员需要两个参数才能构造。你的意思是属于这个组的具体类的构造函数需要两个参数吗?所有参数都是同一类型的吗?如果不是,包括附加的第三个参数在内的每个参数的类型是什么?您的意思是属于该组的混凝土类的构造函数需要两个参数吗?是的,就是这样。所有参数(包括附加参数)都是int.ok类型。这很清楚。假设有两个子类
    subclass 1
    subclass 2
    ,它们的构造函数接受2
    int
    参数。您如何决定这些具体类中的哪一个应该在超类的静态方法中实例化?它是否基于
    int
    参数之一的值?请参阅我的答案并对其进行评论,以了解您的其他疑问。您可以将可选参数设置为vararrg:getSuperClass(字符串类型,int i1,int i2,int…可选)