方法覆盖和为什么输出为零?

huangapple go评论78阅读模式
英文:

Method Override and why output is zero?

问题

public class Test {
    // 一个类需要有一个main()方法
    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);
        }

    }

    // 参数通过下面这个编辑器的文本字段传递
    public static void main(String[] args) {
        MyClass myObject = new MyClass();
        myObject.test();
    }
}
英文:
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();
    }
}

方法覆盖和为什么输出为零?

答案1

得分: 0

以下是翻译好的部分:

结果有些出乎意料(正如您的问题已经暗示的那样),但可以通过Java的初始化顺序来解释:

一般情况下,初始化顺序如下:

  1. 超类的静态块
  2. 类的静态块
  3. 超类的非静态块
  4. 超类的构造函数
  5. 类的非静态块
  6. 类的构造函数

在您的示例中,ParentMyClass 的超类,而 MyClass 重写了 Parenttest() 方法。这意味着在 Parent 的构造函数中执行了 MyClasstest() 实现。由于这是在 MyClass 的非静态块(即 int i = 100;)执行之前调用的,因此在第一次调用 test 时,i 具有其默认值 0。在第二次调用 test() 时,i 已经初始化,因此其值为 100。

如果您想知道为什么 i 是 0 而不是 1000。这是因为在创建具有相同名称字段的子类时,类字段不会被覆盖。也就是说,在 MyClass.test() 中始终使用字段 MyClass.i

英文:

The result is somewhat unexpected (as your question already suggests) but can be explained by Java's initialization order:

The initialization order in general is the following:

  1. Static blocks of the super class
  2. Static blocks of the class
  3. Non-static blocks of the super class
  4. Constructor of the super class
  5. Non-static blocks of the class
  6. Constructor of the class

In your example Parent is a super class of MyClass and MyClass overrides Parent's test() method. That is in the constructor of Parent the test() implementation of MyClass is executed. As this is called before the non-static blocks of MyClass (i.e. int i = 100;) have been executed, i has it's default value 0 in the first call to test. In the second call to test() i has been initialized and thus has it's value of 100 assigned.

If you're wondering why i is 0 and not 1000. This is because class fields are not overridden when creating a sub-class with identically named fields. That is in MyClass.test() always the field MyClass.i is used.

huangapple
  • 本文由 发表于 2020年4月10日 18:26:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/61138345.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定