首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java中,为什么((A)b).disp()调用派生类方法disp()而不是基类方法disp()?

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

Stack Overflow用户
提问于 2015-04-13 08:02:51
回答 4查看 764关注 0票数 3

我在学习Java,是个初学者.请帮我找出为什么这不管用..。

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

如代码所示,主方法中的((A)b).num工作得很好,并且输出了100,正如预期的那样,但是((A)b).disp()输出了B方法中的内容,而不是A的方法。

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

}

产出如下:

代码语言:javascript
复制
Disp() of B:
Disp() of A:
100
200

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

但我的预期产出是:

代码语言:javascript
复制
Disp() of B:
Disp() of A:
100
200


Disp() of A:
100

100

有人能帮我找出这个输出的原因吗?

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

而且这不会给编译错误..。!!提前谢谢..。:)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-04-13 08:33:38

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

假设A有一个整数属性名值,而A.alter()是一个更改该值的方法。假设B扩展了A并重写了该方法,B提供了属性值始终为正的附加保证。A.alter()有时可能导致值为负值,但B.alter()永远不会。

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

票数 1
EN

Stack Overflow用户

发布于 2015-04-13 08:09:02

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

票数 1
EN

Stack Overflow用户

发布于 2015-04-13 08:19:41

你在尝试一些不可能的东西。无法从子类的实例中调用超类的实现(除了通过"super“关键字在子类中调用之外)。

num类变量工作的原因是不能覆盖类变量。在B类型的对象中得到的基本上是2(!)名为num的变量。一个是从A继承的(你通过上播访问它),另一个是从B类继承的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29600549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档