假设我扩展了一个类并覆盖了这个类中的方法。为什么从我的新类的构造函数中调用重写方法是不好的做法?
答案 0 :(得分:12)
不从构造函数调用可覆盖方法的主要原因是它允许子类以半构造状态查看类。这可能是也可能不是安全风险,但这是一个等待发生的错误。阅读更多here。
答案 1 :(得分:5)
在构造函数中完成工作通常是一种不好的做法 - 只需获取并分配对象依赖项。
答案 2 :(得分:3)
有人可以从您的类继承并更改您在构造函数中依赖的行为。
这意味着你不知道你的功能是什么。
答案 3 :(得分:3)
因为类的结果实例可能处于不一致状态。这是一个具体的例子。
public class Foo {
private int number;
public Foo() {
number = 42;
multiplyNumber();
}
public void multiplyNumber() {
number = number * 2;
}
public int getNumber() {
return number;
}
}
public class Bar extends Foo {
private int number;
public Bar() {
multiplyNumber();
}
@Override
public void multiplyNumber() {
number = number * 3;
}
}
public class FooBar {
public static void main(String[] args) {
Foo foo = new Foo();
Foo bar = new Bar();
System.out.println("Foo number 1 = " + foo.getNumber()); // Returns 84
System.out.println("Foo number 2 = " + bar.getNumber()); // Returns 42;
}
}
在我的机器上运行调试时,bar
实际上从未在构造函数中调用multiplyNumber()
方法;它只是被跳过了。因此,该对象在number
中没有预期的值。
构造者应该是简单的生物;最好不要在那里放任何非常复杂的东西。
答案 4 :(得分:1)
想象一下,在构造函数中调用了一个可覆盖的方法。再次进行子类化并再次覆盖。第二个子类可以中断您的第一个子类所依赖的工作被认为是完全初始化的,从而使其处于损坏状态。
至于构造函数中的工作。你可以做的工作,通常应该是初始化对象所需的工作类型。
对于最佳实践,一起避免继承,如果您决定将构造函数划分为方法,请使用可见性修饰符来确保所有工作保持在正在构造的类的本地。