简体   繁体   English

Java - 为什么重写方法被调用两次(或者至少它看起来像这样)?

[英]Java - Why is overriden method being called twice (or at least that's what it seems)?

The below has this output. 下面有这个输出。

Hello World!
main.ConstructedDerivedClass:6.0
main.ConstructedDerivedClass:6.0
public class ConstructedDerivedClass extends ConstructedBase {

    private static final double version = 6.0;

    public static void main(String[] args) {

        System.out.println("Hello World!");

        ConstructedDerivedClass derivedClass = new ConstructedDerivedClass();
    }

    public ConstructedDerivedClass() {
        showMyAttributes();
    }

    @Override
    protected void showMyAttributes() {
        System.out.println(this.getClass().getName() + ":" + version);
    }  
}

public class ConstructedBase {

    private static final double version = 15.0;

    public ConstructedBase() {
        showMyAttributes();
    }

    protected void showMyAttributes() {
        System.out.println(this.getClass().getName() + ":" + version);
    }
}

I would expect it to just display one line, that of the child class (ConstructedDerivedClass). 我希望它只显示一行,即子类的类(ConstructedDerivedClass)。 But instead it print's out twice.I know in general you should avoid calling overriden methods from a constructor, but I wanted to see for myself how was this working. 但它反而打印两次。我知道一般你应该避免从构造函数中调用overriden方法,但我想亲眼看看它是如何工作的。

Actually, I get why version is '6.0' on both lines - since field is being declared static of course static fields are initialized first. 实际上,我知道为什么版本在两行上都是'6.0' - 因为字段被声明为静态,当然静态字段首先被初始化。 But still don't get why two lines. 但仍然不明白为什么两行。

Any guidance would be appreciated. 任何指导将不胜感激。

This is because when you write 这是因为你写的时候

public ConstructedDerivedClass() {
    showMyAttributes();
}

The compiler actually places a call to super default constructor in byte code so it's equivalent to 编译器实际上在字节代码中调用超级默认构造函数,因此它等效于

public ConstructedDerivedClass() {
    super();        
    showMyAttributes();
} 

When an object is instantiated, it makes an implicit, no-args super-constructor call to its parent class before running its own constructor. 当一个对象被实例化时,它会在运行自己的构造函数之前对其父类进行implicit, no-args超构造函数调用。

You can imagine that there is this line ALWAYS in your constructors: 你可以想象在你的构造函数中总是存在这一行:

public MyClass() {
    super(); //If this line is not here, it is implicit.
    //rest of the code
}

You can override this by providing your own explicit, any-args super-constructor call, but it must be the first line of the method. 您可以通过提供自己的explicit, any-args超构造函数调用来覆盖它,但它必须是方法的第一行。

public MyClass() {
    super(1, "Hello Word", null); //written explicitly, no other super-constructor code will run
    //rest of the code
}

Which can be useful when the superclass does not have a no-args constructor defined. 当超类没有定义no-args构造函数时,这可能很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM