方法覆盖以及为什么输出为零?
Method Override and why output is zero?
public class Test {
// one class needs to have a main() method
public static class Parent {
int i = 1000;
Parent() {
test();
}
public void test() {
System.out.println("Parent: " + i);
}
}
public static class MyClass extends Parent {
int i = 100;
MyClass() {
super();
}
public void test() {
System.out.println("MyClass: " + i);
}
}
// arguments are passed using the text field below this editor
public static void main(String[] args) {
MyClass myObject = new MyClass();
myObject.test();
}
}
结果有些出乎意料(正如您的问题已经暗示的那样),但可以通过 Java 的初始化顺序来解释:
一般的初始化顺序如下:
- 超级静态块class
- class
的静态块
- 超级的非静态块class
- 超级构造函数class
- class
的非静态块
- class
的构造函数
在您的示例中,Parent
是 MyClass
的超级 class,并且 MyClass
覆盖了 Parent
的 test()
方法。即在 Parent
的构造函数中执行 MyClass
的 test()
实现。由于这是在 MyClass
的非静态块(即 int i = 100;
)执行之前调用的,因此 i
在第一次调用 test
时具有默认值 0。在对 test()
的第二次调用中,i
已被初始化,因此分配了 100 的值。
如果您想知道为什么 i
是 0 而不是 1000。这是因为在创建具有相同名称字段的子 class 时,不会覆盖 class 字段。那就是在 MyClass.test()
中总是使用字段 MyClass.i
。
public class Test {
// one class needs to have a main() method
public static class Parent {
int i = 1000;
Parent() {
test();
}
public void test() {
System.out.println("Parent: " + i);
}
}
public static class MyClass extends Parent {
int i = 100;
MyClass() {
super();
}
public void test() {
System.out.println("MyClass: " + i);
}
}
// arguments are passed using the text field below this editor
public static void main(String[] args) {
MyClass myObject = new MyClass();
myObject.test();
}
}
结果有些出乎意料(正如您的问题已经暗示的那样),但可以通过 Java 的初始化顺序来解释:
一般的初始化顺序如下:
- 超级静态块class
- class 的静态块
- 超级的非静态块class
- 超级构造函数class
- class 的非静态块
- class 的构造函数
在您的示例中,Parent
是 MyClass
的超级 class,并且 MyClass
覆盖了 Parent
的 test()
方法。即在 Parent
的构造函数中执行 MyClass
的 test()
实现。由于这是在 MyClass
的非静态块(即 int i = 100;
)执行之前调用的,因此 i
在第一次调用 test
时具有默认值 0。在对 test()
的第二次调用中,i
已被初始化,因此分配了 100 的值。
如果您想知道为什么 i
是 0 而不是 1000。这是因为在创建具有相同名称字段的子 class 时,不会覆盖 class 字段。那就是在 MyClass.test()
中总是使用字段 MyClass.i
。