建立子类对象时,父类构造函数中调用被子类重写的方法为何调用的是子类的方法?

问题:建立子类对象时,父类构造函数中调用被子类重写的方法为何调用的是子类的方法,而被子类重载的方法不会调用?java

public class Basic{
    public void add(int i)
    {
        System.out.println("Basic add");
    }
    
    public Basic()
    {
        add('a');
    }
}

public class A extends Basic{
    public void add(int i)
    {
        System.out.println("A add");
    }
}

public class B extends Basic{
    public void add(char i)
    {
        System.out.println("B add");
    }
}

public class Main{
    public static void main(String[] args)
    {
        A a = new A();
        B b = new B();
    }
}

问题:为何建立A对象的时候父类会调用子类方法? 可是:建立B对象父类会调用父类的方法?函数

答案: 当子类被加载到内存方法区后,会继续加载父类到内存中。 若是,子类重写了父类的方法,子类的方法引用会指向子类的方法,不然子类的方法引用会指向父类的方法引用。 若是子类重载了父类方法,则子类重载方法引用还指向子类方法。 若是子类方法没有重写也没有重载父类方法,则方法引用会指向父类方法。code

当子类对象建立时,会先行调用父类的构造方法(构造方法也是方法),虚拟机会在子类方法区寻找该方法并运行。 可是:因为java语言是静态多分派,动态单分派。其结果是当编译的时候,父类构造方法调用的方法的参数已经强制转换为符合父类方法的参数了。 上边代码在编译前已经转换为下面这个样子的了。对象

public class Basic{
    public void add(int i)
    {
        System.out.println("Basic add");
    }
    
    public Basic()
    {
        add((int)'a');
    }
}

public class A extends Basic{
    public void add(int i)
    {
        System.out.println("A add");
    }
}

public class B extends Basic{
    public void add(char i)
    {
        System.out.println("B add");
    }
}

public class Main{
    public static void main(String[] args)
    {
        A a = new A();
        B b = new B();
    }
}

看一下上边的代码,是否是恍然大悟?blog

更多文章:http://blog.gavinzh.com内存

相关文章
相关标签/搜索