在Java中,为什么((A)b).disp()调用派生类方法disp()而不是基类方法disp()?

时间:2015-04-13 08:02:52

标签: java

我正在学习Java,我是初学者...请帮助我找出为什么这不起作用......

在下面的程序中,我的目的是从main方法调用基类方法,而不在派生类方法中使用super关键字。

如代码所示,((A)b)主方法中的.num完全正常,输出100,如预期的那样,但是((A)b).disp()输出B方法中的内容,而不是A的方法。

class A
{
    int num=100;

    public void disp()
    {
    System.out.println("Disp() of A:");
    System.out.println(num);
    }

}

class B extends A
{
    int num=200;

    public void disp()
    {
    System.out.println("Disp() of B:");
    super.disp();              //100
    System.out.println( num );  //200
    }

}

class ques
{

    public static void main(String a[])
    {
    B b=new B();

    b.disp();         

    System.out.println();
    ((A)b).disp();                          //doesn't work

    System.out.println();
    System.out.println(((A)b).num);         //works
    }

}

输出是:

Disp() of B:
Disp() of A:
100
200

Disp() of B:
Disp() of A:
100
200
100

但我的预期输出是:

Disp() of B:
Disp() of A:
100
200


Disp() of A:
100

100

任何人都可以帮我找到输出的原因。

为什么((A)b).num工作正常,((A)b).disp()没有按预期工作......

此外,这不会给出编译错误.... !!在此先感谢.. :))

3 个答案:

答案 0 :(得分:1)

字段访问在编译时解析,而实例(非静态)方法调用总是动态调度。 JVM并不关心您将b强制转换为A,它始终会对disp()的实际运行时类型调用b

答案 1 :(得分:1)

你正在尝试一些不可能的事情。无法从子类的实例调用超类的实现(通过“super”关键字在子类中除外)。

num class变量的工作原理是,您无法覆盖类变量。你在B类对象中得到的基本上是名为num的两个(!)变量。一个继承自A(你通过upcast访问它)和一个来自B类。

答案 2 :(得分:1)

必须以这种方式保留派生类的语义。

想象一下A有一个整数属性名 value ,而A.alter()是一个改变该值的方法。想象一下,B扩展了A并覆盖了该方法,并且B提供了属性 value 始终为正的额外保证。 A.alter()有时可能导致值为负,但B.alter()永远不会。

如果((A)b).alter()在类型B的对象上调用A.alter()方法,结果可能是具有负值的B:B应该具有的保证被打破了。