简体   繁体   English

Java:从超类构造函数中的子类调用的方法

[英]Java:Method called from subclass in superclass constructor

class AA{
    int x;
    protected AA(){init (1008);}
    protected void init(int x)
    {
        this.x = x;
    }
}

class BB extends  AA{
    public BB() {
        init(super.x * 2);
    }
    public void init(int x)
    {
        super.x = x+1;
    }
}
public class Main  {

    public static void main(String[] args) {
        BB tst = new BB();
        System.out.println(tst.x);
    }
}

I know that this code will print 2019. Yet I do not understand why the superclass constructor,when called, will use the init method from de subclass instead the one from the superclass. 我知道这段代码将在2019年打印。但是我不明白为什么超类构造函数在被调用时会使用de子类中的init方法而不是超类中的init方法。

Yet I do not understand why the superclass constructor,when called, will use the init method from de subclass instead the one from the superclass. 但是我不明白为什么超类构造函数在被调用时会使用de subclass中的init方法而不是超类中的init方法。

Because that's the one associated with the object being constructed. 因为那是与正在构造的对象相关联的对象。 this within the superclass constructor is a reference to the subclass object being constructed, so just like any other call to init using that reference, it uses the subclass's init . 超类构造函数中的this是对正在构造的子类对象的引用,因此,就像使用该引用进行的对init任何其他调用一样,它也使用子类的init

This may help, note the lines with comments on the end — the comments say what those lines output: 请注意最后带有注释的行,这可能会有所帮助-注释说明了这些行的输出:

class AA{
    int x;
    protected AA() {
        System.out.println(this.getClass().getName()); // "BB"
        System.out.println(this instanceof BB);        // true
        init(1008);
    }
    protected void init(int x)
    {
        this.x = x;
    }
}
class BB extends  AA{
    public BB() {
        init(super.x * 2);
    }
    public void init(int x)
    {
        super.x = x+1;
    }
}
public class Main  {

    public static void main(String[] args) {
        BB tst = new BB();
        System.out.println(tst.x);
    }
}

It's because subclasses can override methods that calling non- final , non- private methods from a constructor is usually best avoided. 这是因为子类可以覆盖方法,因此通常最好避免从构造函数中调用非final ,非private方法。

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

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