前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >创建子类对象时,父类构造函数中调用被子类重写的方法为什么调用的是子类的方法?

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

作者头像
zhangheng
发布2020-04-28 17:47:15
6K0
发布2020-04-28 17:47:15
举报
代码语言:javascript
复制
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对象父类会调用父类的方法?

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

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

代码语言:javascript
复制
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();
    }
}

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-07-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档