什么';java虚拟方法调用的使用是什么?

什么';java虚拟方法调用的使用是什么?,java,polymorphism,Java,Polymorphism,假设我有以下代码 public class A { public void callme() { System.out.println("Calling of class A function "); } } public class B extends A { public void callme() { System.out.println(" Calling of class B fuction "); } public void Hello() {

假设我有以下代码

public class A {
  public void callme() {
    System.out.println("Calling of class A function ");
  }
}

public class B extends A {
  public void callme() {
    System.out.println(" Calling of class B fuction ");
  }

  public void Hello() {
    System.out.println("hello guys");
  }
}
还有一个main(),它执行以下操作

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

    b = (B)a;
    a.callme();
    b.callme();
    a.Hello(); // show error : Hello is undefined for method A
  }
}

这本书说“您可以在运行时获得与变量引用的对象相关联的行为”。好的,当调用方法callme时,我得到了B类的行为,但是当我访问方法Hello时,它显示了一个错误,即方法a的Hello未定义。这是为什么?

a
的类型是
a
,即使它引用的是
B
的实例

A
没有
Hello
方法(甚至是
摘要
声明)。因此编译器会发出错误。将代码稍微调整为

public abstract class A {
    public abstract void Hello();
    /*the rest as before*/

这将是一个解决办法<代码>一个然后假设接口的特性。

多态性不是这样工作的。由于A是B的父级,B可以继承A的方法(就像子可以继承父级的属性一样),但反之亦然,因为A不知道哪些类继承它(A不知道谁是它的子级)

例如,假设还有一个C类:

public class C extends A {
public void callme(){

System.out.println(" Calling of class C fuction ");
}

public void Hello(){

System.out.println("hello guys, I am C");
}
}
现在,如果你使用

a.Hello();
既然一个类不知道它的子类的方法,它怎么知道应该调用哪个子类呢。只有它自己的抽象方法,它知道child肯定会实现它

public class B extends A {
public void callme(){

System.out.println(" Calling of class B fuction ");
}

public void Hello(){ // hello method is only the part of class B not A.

System.out.println("hello guys");
}
}
在上面的类中,
hello()
方法只是B的一部分。它不会被A的方法覆盖

现在在主方法调用中

public static void main(String [] args){
A a= new B();  // object of b referred by (a) Reference Variable of A
B b= new B();  // object of b referred by (b) Reference Variable of B

b= (B)a;
a.callme();  //override takes place and method of B's Callme() called
b.callme();  //again override takes place here and method of B's Callme() called
a.Hello();// buttttttt
b.Hello(); // this will compile and executes fine.
}
}
这里您使用了类
A
的引用变量,它没有任何方法名
Hello()
。因此,方法解析将不会发生(将无法找到任何类似
Hello()
)的方法)

但是,如果您尝试使用
b
的引用变量调用
b.Hello()
,那么它对您来说可以正常工作

现在假设还有另一个类C,它是a的一个子类,包含一个方法名
Hello()

主要是这样一种说法

A a = new C();
如果您试图调用
a.Hello()
,那么将调用哪个
Hello()
方法。编译器会感到困惑


因此,只有当您试图重写子类中的超类方法时,这个概念才起作用。

父类是否知道从它派生的类

强制转换不会更改实际对象类型。只更改引用类型。


我强烈建议您从

向上和向下转换写入,因为变量
a
的类型为
a
,类
a
没有
Hello
方法。行为!=那么A=new B()的好处是什么虚拟方法调用..我可以简单地使用B类的对象来调用函数。为什么我们使用虚拟方法调用?
A a = new C();