覆盖构造函数
我对Overriding Constructors非常困惑。 构造函数不能被覆盖是我在谷歌搜索它时得到的结果我的问题是
public class constructorOverridden { public static void main(String args[]) { Sub sub = new Sub(); sub.test(); } } class Super { Super() { System.out.println("In Super constructor"); test(); } void test() { System.out.println("In Super.test()"); } } class Sub extends Super { Sub() { System.out.println("In Sub constructor"); } void test() { // overrides test() in Super System.out.println("In Sub.test()"); } }
当我运行这个时,我得到了结果
In Super constructor In Sub.test() In Sub constructor In Sub.test()
请注意子类中的测试方法已执行。 是否显示超级构造函数被覆盖。 是否正确?
构造函数不是多态的 – 你根本不会覆盖它们。 您在子类中创建新构造函数,并且每个子类构造函数必须链接(可能是间接)到超类构造函数。 如果没有显式链接到构造函数,则会在子类构造函数体的开头插入对无参数超类构造函数的隐式调用。
现在就重写方法而言 – 一个对象从一开始就是“最终类型”,包括执行超类构造函数时。 因此,如果在Super
构造函数代码中打印getClass()
,您仍会在输出中看到Sub
。 结果就是调用了重写方法(即Sub.test
),即使Sub
构造函数尚未执行。
这基本上是一个坏主意,你应该几乎总是避免在构造函数中调用可能被覆盖的方法 – 或者非常清楚地记录它将是这种情况(因此子类代码意识到它不能依赖已经存在的变量)适当初始化等)。
您无法覆盖构造函数,因为构造函数是由它构造的类的名称调用的。 如何使用相同的构造函数创建一些不同的类? 此外,子类不会从其父级inheritance构造函数。
如果父构造函数执行了一些重要的初始化,则可以使用super从子构造函数调用它:
class Err extends Throwable { Err(String message) { super(message); // Call the constructor of Throwable. ..
父类构造函数也始终被调用。 如果您自己不调用any,则在输入派生类的构造函数之前会自动调用不带参数的构造函数。 如果父级没有无参数构造函数而您没有调用任何构造函数,则会报告编译时错误。
构造函数的第一个隐含行是对Super()
的调用。 这就是你获得这些结果的原因。
那是对的。 实例化子类时,首先调用超类构造函数,然后调用层次结构中的每个连续构造函数。
在上面的示例中,超类构造函数调用重写方法( test()
)。 这有效,但由于尚未调用子类构造函数,因此存在潜在的危险,并且您的子类尚未完全初始化。 因此,在构造函数中调用重写(或可重写)方法并不是一种好习惯。
它不会覆盖超类构造函数,并且构造函数不能被覆盖它可以重载。
当您创建子类对象时,将首先实例化超类,然后将实例化子类。 如果没有父母,它就像孩子一样不存在 。
编译器将自动从子类构造函数中调用超类构造函数。
Sub() { super(); System.out.println("In Sub constructor"); }