Java超类实例化调用子类方法,不知道为什么

时间:2012-04-12 19:54:01

标签: java override subclass superclass

所以我遇到了类似这样的问题:

package com.blah.A_package;

public class A
{
    public void f() {
        g();
    }

    protected void g() {
        System.out.println("superclass g()");
    }
}

package com.blah.B_package;

public class B extends com.blah.A_package.A
{
    protected void g() {
        System.out.println("subclass g()");
    }
}

public static void main(String[] args)
{
    A scratch = new A();
    scratch.f();
}

运行时,它打印出“子类g()”而不是预期的“超类g()”。

我们实际上正在创建超类和子类的对象(这是通过jar上的反射),将它们粘贴在地图中,然后根据需要将它们拉出来,但我们已通过打印出来验证了object.getClass()。getName(),看到我们实际上正在使用超类实例化。

无论如何,当我们运行应用程序时,由于某种原因,它使用方法的子类副本而不是超类,尽管对象是超类的实例化(即,它甚至不应该知道子类方法) 。这是我和我的同事不知道的已知事物吗?我们完全不知道为什么会发生这种情况。

2 个答案:

答案 0 :(得分:0)

简而言之,唯一可能导致此问题的是运行时对象是B的实例,但是您将其声明为A.当调用该方法时,您的程序将开始查看运行时类的它被调用的对象,然后继承继承树。

在旁注中,您缺少构造函数,您的B类扩展了一个包,并且您的方法没有返回类型。这完全是无效的Java。

答案 1 :(得分:0)

可能导致混淆的一件事是B的子类与其超类(A具有相同的名称,但在具有相似名称的不同包上A超类的包。

除此之外,它看起来像分析错误。回顾你的步骤。一些想法:删除类B或使其不可实例化,然后重新引入它并再次测试它。