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

在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()

我正在学习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() 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,我理解你的问题,也理解你的答案:)