在Java中,((A)b).disp()为什么调用派生类方法disp()而不是基类方法disp()?
我正在学习Java,我是一个初学者。。。请帮我找出这不起作用的原因 在下面的程序中,我的目标是从main方法调用基类方法,而不在派生类方法中使用super关键字 如代码所示,main方法中的((A)b).num工作得非常好,输出值如预期的那样为100,但是((A)b).disp()输出b方法中的内容,而不是A方法中的内容在Java中,((A)b).disp()为什么调用派生类方法disp()而不是基类方法disp()?,java,Java,我正在学习Java,我是一个初学者。。。请帮我找出这不起作用的原因 在下面的程序中,我的目标是从main方法调用基类方法,而不在派生类方法中使用super关键字 如代码所示,main方法中的((A)b).num工作得非常好,输出值如预期的那样为100,但是((A)b).disp()输出b方法中的内容,而不是A方法中的内容 class A { int num=100; public void disp() { System.out.println("Disp()
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()未按预期工作
此外,这不会导致编译错误!!提前感谢……) 字段访问在编译时解析,而实例(非静态)方法调用始终动态调度。JVM不关心您是否正在将
b
强制转换为A
,它将始终在实际运行时类型b
上调用disp()
,您正在尝试一些不可能的事情。无法从子类的实例调用超类的实现(除了通过“super”关键字在子类中)
num类变量工作的原因是,您不能重写类变量。在类型B的对象中得到的基本上是两个名为num的(!)变量。一个是从A继承的(通过向上转换访问),另一个是从类B继承的。必须这样才能保留派生类的语义 假设A有一个整数属性名值,而A.alter()是一个更改该值的方法。假设B扩展了A并覆盖了该方法,B提供了属性值始终为正的额外保证。A.alter()有时可能导致值为负值,但B.alter()永远不会
如果((A)b).alter()对类型为b的对象调用了A.alter()方法,结果可能是b具有负值:b应该具有的保证将被打破。正如您告诉aim的那样,在不使用super关键字的情况下调用基类方法,下面是解决方案
class A {
A() {
int num=100;
System.out.println("Value of A: ");
System.out.println(num); //100
}
}
class B extends A {
B() {
int num=200;
System.out.println("Value of B: ");
System.out.println(num); //200
}
}
class ques {
public static void main(String a[])
{
B b=new B();
}
}
O.p
A值:100
B值:200
这是怎么发生的?
一般情况下,如果您想访问超类的方法,超级关键字是必不可少的,但有一种方法可以省略“超级”关键字
- 使用不带参数的构造函数作为构造函数在声明时初始化方法/变量,因此不需要调用
如果您使用参数调用构造函数 比如说 公共A(国际一)
然后您必须强制使用super关键字,因为这样您就必须在这里传递integer类型的值。我建议您阅读java中的
多态性。在java中,您可以将一个超类引用分配给一个子类对象,因此在运行时要调用的实际方法取决于分配给该引用的实际对象,这是在B中重写a的disp()的效果。您可以使用构造函数启动或有一种方法实现对超类方法的调用(不使用“Super”),我在同一页中发布了签出答案。这是因为每个构造函数都有一个隐式的super()
调用,除非另有规定。Quote:“如果构造函数体不是以显式构造函数调用开始,并且所声明的构造函数不是原始类对象的一部分,那么构造函数体隐式地以超类构造函数调用“super()开始;“,对其直接超类的构造函数的调用,不带任何参数。”因此,超级调用并不明确,因为概念比以前更清晰,谢谢!非常感谢。但请仔细阅读,我已经写了,我的目标是“从主方法调用基类方法”,在派生类方法中不使用super关键字,这里你使用了构造函数并执行了这个任务,比较了“工作”和“不工作”的语句。。。。在我的节目中。。。我想知道为什么这不起作用……谢谢@soylentgreen81Yes,我理解你的问题,也理解你的答案:)