java - 从构造函数调用重写的方法

标签 java constructor

在下面的例子中:

class Base {    
    int  x=10;  

    Base() {    
      show();
    }  

    void show() {   
        System.out.print ("Base Show " +x + "  ");
    }  
}  

class Child extends Base {   
    int x=20;  

    Child() {
        show();
    }  

    void show() {    
        System.out.print("Child Show " + x +"  ") ; 
    }  

    public static void main( String s[ ] ) {   
        Base obj = new Child();   
    }  
} 
  • 为什么输出如下图
Child Show 0  Child Show 20
  • 我认为构造函数只能在 super 构造函数完成后才能访问实例成员。

我认为这里发生的事情是 super 构造函数正在调用 child 的 show() 方法,因为这个方法在 Child 中被覆盖了。因为它已被覆盖,但为什么 x 的值为 0,为什么它能够在 super 构造函数完成之前访问此方法?

最佳答案

I think what is happening here is that the super constructor is calling the child's show() method because this method was overriden in Child.

没错

but why is the value of x 0

因为它还没有初始化(x of Child)

and why is it able to access this method before the super constructor has completed?

这就是为什么在构造函数中永远不应该调用可以被覆盖(非最终公共(public)和 protected )的方法。

编辑:

这里的奇怪之处在于所有内容都具有默认/包私有(private)的可见性。这可能会产生一些奇怪的效果。请参阅:http://www.cooljeff.co.uk/2009/05/03/the-subtleties-of-overriding-package-private-methods/

我建议尽可能避免覆盖具有默认可见性的方法(您可以通过将它们声明为 final 来防止这种情况发生)。

关于java - 从构造函数调用重写的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8450133/

相关文章:

Java 扩展泛型

java - 如何在 Maven Mojo 中使用整个插件配置

json - dart 中 json 映射的工厂和命名构造函数

scala - 在scala中创建新对象后的代码块

java - 如何将 Eclipse 同时用于 Java 和 PHP?

java - 我可以将多个表单输入绑定(bind)到一个 bean 的一个属性吗?

java - 错误: java. lang.ClassNotFoundException :com. mysql.jdbc.Driver

c++ - 这两个构造函数调用之间的区别

spring - 我可以在 spring 配置文件中为构造函数参数默认系统属性吗?

java - 为什么我不能在 Java 中扩展具有不明确构造函数的类?