java - java中的方法覆盖和继承

标签 java overriding

考虑以下代码段:

class A{ /* assume static and non static block are here */ }
class B extends A{ /* assume static and non static block are here */ }

在主方法中,

 new B();

所以初始化的顺序是:

  1. 类A的静态成员初始化
  2. 类B的静态成员初始化
  3. 类A的非静态成员初始化
  4. 然后执行构造函数A中的代码
  5. 类B的非静态成员初始化
  6. 然后执行构造函数B中的代码

现在看看这段代码,

class A{
    A(){
        this.m(); //line 1
    }

    void m(){
        System.out.println("A.m()");
    }
  }

  class B extends A{
     void m(){
        System.out.println("B.m()");
    }
  }

在主方法中,

 new B();

当构造函数A的代​​码正在执行时,它只能看到类A中的方法m,因为类B的非静态成员尚未初始化(根据我提到的顺序)。 然而结果是“B.m()”。 (子类的方法已经执行) 考虑到我提到的顺序,有人可以解释这里发生了什么(方法覆盖)吗?

最佳答案

When the code of constructor A is being executed, it can only see the method m in class A since non static members hasn't been initialized yet for class B (according to the order I mentioned).

您假设方法是已初始化的“非静态成员”的一部分。事实并非如此 - 这实际上是 B 中的 fieldsA 构造函数完成时被初始化的问题。

一旦在 Java 中创建了一个对象,它的类型就被设置并且永远不会改变。为所有字段分配了足够的空间 - 但这些字段实际上是从继承层次结构的顶部向下初始化的。

所以是的,如果您从构造函数调用重写的方法,它将在它想要使用的某些字段未初始化的上下文中执行 - 因此您应该尽可能避免这样做。

关于java - java中的方法覆盖和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18190825/

相关文章:

swift - 在 init 上设置变量和在 Swift 中覆盖该变量之间的区别?

java - 即使在 Struts 2.3.24 中添加 commons-lang3 库后也出现 NoClassDefFoundError

java - 迭代字符串以验证它是否是二进制数

Java 计算 C(n,k) 和带有大整数的阶乘

java - Spring中无法导入 `configureRepositoryRestConfiguration`

java - 使用泛型参数重写方法

c++ - 重载方法覆盖 : Is there any simplification?

java - 返回 super.onOptionsItemSelected(item);没有调用父方法

java - 自定义 JavaFX 8 对象

perl - 从 Perl 中的 carp 模块覆盖 croak cluck confess carp