请教大家一个 java 多态在对象创建中的问题。

2016-02-15 16:38:08 +08:00
 palmers

问题是这样的,先看一段代码 :

public class A {

    public int num = 1 ;

    public A() {
        fun();
        System.out.println("A constuctor.");
    }

    public void fun() {
        System.out.println("A func." + num);
    }
}

类 C:

public class C extends A {

    public int nu = 100 ;
    public static int no = 101 ;

    public C() {
        System.out.println("C constuctor.");
    }

    @Override
    public void fun() {
        System.out.println("C func." + nu + " --- " + no);
    }
}

以上代码中,父类 A 在构造方法中调用了一个子类覆写的方法, 经过测试,在实例化 C 类对象时可以正常调用 C 类中 fun 方法 (覆写父类方法),只是 C 类成员属性没有初始化完成。
我想不明白,在 C 类没有构造完成的时候怎么可以调用对象方法呢? 目前我看不懂 JVM 原理,请知道这块的朋友帮我详细解释下,非常感谢!


测试代码就一行:

C c = new C() ;
3229 次点击
所在节点    程序员
21 条回复
palmers
2016-02-16 09:15:43 +08:00
@zonghua 这里 C 继承 A 初始化 C 之前需要先初始化 A, 因为 C 默认显式继承了 A 的部分信息,如果 A 没有初始化,则 A 的初始化信息 C 也就拿不到,严格上 C 是不能使用的。所以 A 需要得到初始化。 所以在默认情况下 C 初始化之前会隐式调用父类默认构造方法,保证父类(基类)能在子类初始化之前得到初始化。

关于在 A 构造方法中调用了子类方法,其实是因为多态特性, JVM 发现 fun 方法被子类覆写,则调用了子类 fun 方法,实现方法多态,这个我觉得是因为当前类型信息为 C 所以才会调用 fun 的。

以上是我的理解,你可以参考,但不一定正确。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/256646

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX