繁体   English   中英

Java - 如何根据继承类的构造函数参数调用不同的super()?

[英]Java - how to call different super() according to inheriting class's constructor argument?

我试图让继承类要求更少的参数,并计算超类的'正确'mising参数。 寻求有关如何执行此操作的帮助,而不使用工厂方法。

这是简化操作的示例代码。 Son(int)将根据int的值调用super(int,boolean)。

class Base {
  ...
  public Base (int num, boolean boo2) { ...}
  ...
}

class Son extends Base {
  ...
  public Son (int num) {
    if (num > 17)
       super(num, true);
    else
      super(num , false);
  }
  ...
}

我还考虑过将Base作为接口,但这不允许我强制执行一些参数正确性检查。

感谢您的帮助。

我不是百分百肯定,但这可以吗?

class Son extends Base {
  ...
  public Son (int num) {
       super(num, (num>17));
  }
  ...
}

super()调用必须是构造函数中的第一个语句。 在这种情况下,您可以使用:

class Base {
    public Son(int num) {
        super(num, num > 17);
    }
}

如果您需要执行的计算工作比单个表达式长,则可以将其移动到从构造函数调用的静态方法中:

class Son extends Base {
    public Son(int num) {
        super(num, calcBoo(num));
    }

    private static boolean calcBoo(int num) {
        if (num > 17)
            return true;
        else
            return false;
    }
}

另一种选择是隐藏构造函数并添加一个静态工厂方法,这将允许您在调用超级构造函数之前执行任意复杂的工作:

class Son extends Base {
    private Son(int num, boolean boo) {
        super(num, boo);
    }

    public static Son create(int num) {
        boolean boo;
        // ... statements here ... //
        return new Son(num, boo);
    }
}

如果找到其他参数是一个复杂的操作(即,不能简化为单个表达式),您可以添加一个静态方法,为您执行此操作并在超级调用中引用它,如下所示:

Class Son extends Base {

  private static boolean getMyBoolean(int num) {
    return num > 17; //or any complex algorithm you need.
  }

  public Son (int num) {
    super(num, getMyBoolean(num));
  }
  ...
}

否则,如果可以使用简单表达式计算缺少的参数(如您给出的具体示例),只需写:

Class Son extends Base {
  public Son (int num) {
    super(num, num > 17);
  }
  ...
}

请注意,构造函数调用必须是构造函数中的第一个语句 所以你需要:

public Son (int num) {
   super(num, (num>17));
}

这将做同样的事情,因为num > 17将被计算为truefalse ,并且它是构造函数中的第一个语句,因此它将被编译。

查看文档

调用超类构造函数必须是子类构造函数中的第一行。

构造函数中的第一行必须是对super的调用,否则你就无法拥有它。

为什么不把行为推到Base类? 无论如何,这将是解决这个问题的更好方法。

所以你会有类似的东西:

Son {
  super(num,17); //in base, you have a "break point" parameter
  ....
}

来自JLS§8.8.7

构造函数体的第一个语句可能是对同一个类或直接超类( §8.8.7.1 )的另一个构造函数的显式调用。

\n ConstructorBody:\n     {ExplicitConstructorInvocation opt BlockStatements opt }\n

super()的调用必须是构造函数的第一个语句 幸运的是,在你的情况下,有一种简单的方法来浓缩它,正如已经提到的:

public Son(int num) {
    super(num, num > 17);
}

我假设您要求调用super是构造函数中的第一行。

你可以使用像其他答案一样的简单布尔表达式,或者你可以推广解决方案(如果你的例子只是一个例子)并使用一个返回正确值的内联函数调用。 您也可以查看三元运算符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM