我正在学习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()没有按预期工作......
此外,这不会给出编译错误.... !!在此先感谢.. :))
答案 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应该具有的保证被打破了。