Java 无序链式构造函数
Java不允许链式构造函数不是放入构造函数中的第一个方法。 链式构造函数不能将非静态方法作为参数调用(这就排除了使用初始化器返回初始化值的可能性)Java 无序链式构造函数,java,inheritance,constructor,Java,Inheritance,Constructor,Java不允许链式构造函数不是放入构造函数中的第一个方法。 链式构造函数不能将非静态方法作为参数调用(这就排除了使用初始化器返回初始化值的可能性) 如何使用合法Java实现上述代码?编辑事实上,Java不允许构造函数在调用父类构造函数之前进行任何计算,即使这些计算只涉及静态方法(正如您的calculateX所应该的那样)并且结果仅分配给类专用的变量(如\u a、\u b和\u c)或构造函数的本地变量 public class ParentClass { public ParentCla
如何使用合法Java实现上述代码?编辑事实上,Java不允许构造函数在调用父类构造函数之前进行任何计算,即使这些计算只涉及静态方法(正如您的
calculateX
所应该的那样)并且结果仅分配给类专用的变量(如\u a
、\u b
和\u c
)或构造函数的本地变量
public class ParentClass
{
public ParentClass(int param);
}
public class MyClass extends ParentClass
{
private int _a;
private int _b;
private int _c;
public MyClass(String input)
{
_a=CalculateA(input);
_b=CalculateB(_a);
_c=CalculateC(_a);
super(_b+_c);
}
//a expensive procedure
private int CalculateA(String text);
private int CalculateB(int a);
private int CalculateC(int a);
}
但是,有一种方法可以解决这个问题:调用另一个构造函数,并将calculateX
调用的结果分配给它的参数,然后您可以通过另一个构造函数访问这个结果
public class ParentClass
{
public ParentClass(int param);
}
public class MyClass extends ParentClass
{
private int _a;
private int _b;
private int _c;
public MyClass(String input)
{
_a=CalculateA(input);
_b=CalculateB(_a);
_c=CalculateC(_a);
super(_b+_c);
}
//a expensive procedure
private int CalculateA(String text);
private int CalculateB(int a);
private int CalculateC(int a);
}
编辑2如果要存储更多的计算结果或更多的中间结果以供以后使用,这种方法将导致一个更长的构造函数链,它只包含此(…)
-调用。只有两个构造函数(public-one和private)的更奇特的解决方案可以使用helper类(合理地说是一个内部类):
(使用与上述相同的私有字段和静态
calculateX
方法)。您可以这样做
public MyClass(String input) {
this(new InitCalcResult(input));
}
private MyClass(InitCalcResult initCalcResult) {
super(initCalcResult.initB + initCalcResult.initC);
this._a = initCalcResult.initA;
this._b = initCalcResult.initB;
this._c = initCalcResult.initC;
}
private static class InitCalcResult {
private int initA, initB, initC;
InitCalcResult(String input) {
initA = calculateA(input);
initB = calculateB(initA);
initC = calculateC(initA);
}
}
由于getData是抽象的,因此将调用基类函数。超级类将获得所需的数据 问题是什么?构造函数可以调用非静态方法。“构造函数也不能调用非静态方法。”这对我来说是个新闻。我敢肯定我在构造函数中使用了大量的方法。那么问题是什么呢?现在您已经做了一个声明。
param
对父类是私有的吗?一定要这样吗?如果没有,您可以调用super(-1)
(或另一个伪值),在子类构造函数中进行计算,然后分配参数=_b+_c
.param实际上是构造函数的一个参数,它根本不存储在父类中。(除了构造器中的本地内容)这是我的原创剧本。问题是我仍然需要_a。@oxiabox在我的super
调用的行中计算\u a
的值,然后通过calculateb plusc传递给calculateb和calculateC。你是说你还需要_a供以后使用吗?事实上,我需要_a、_b和_c供以后使用,我考虑过静态工厂方法。问题是这个局部库中的所有其他类都是用这些构造函数实例化的。我的主管会一直这样做(而且有很好的理由),我认为确实有办法得到你想要的东西。我已经替换了我以前的答案,因为我认为新方法好得多(但感谢你接受了答案,即使它没有完全回答你的问题;-)-这可能有效,而不是抽象的,因为父类不是抽象类。但是virtual(等等,virtual是java的默认值,对吗?)。虽然很混乱,但Parent是另外两个类的基类,并且本身就是一个功能类。此外,父级的构造函数实际上将链向前链接到“祖父母”的构造函数。它变得更加混乱,因为在我的示例中,Paret构造函数只有1个参数,实际上是5。不要这样做。如果有人使用在子类的构造函数中初始化的字段来实现抽象方法,那么调用该方法时,该字段仍然是null
。这可能会导致一些模糊的错误。
public abstract class ParentClass
{
public ParentClass(String input){
int a = getData(input);
/* Do what ever u need to do with a*/
};
public abstract int getData(String input);
}
public class MyClass extends ParentClass
{
private int _a;
private int _b;
private int _c;
public MyClass(String input)
{
super(input);
}
public int getData(String input){
_a=CalculateA(input);
_b=CalculateB(_a);
_c=CalculateC(_a);
return _b+_c;
}
//a expensive procedure
private int CalculateA(String text){/* return int */};
private int CalculateB(int a){/* return int */};
private int CalculateC(int a){/* return int */};
}