什么是java虚方法调用的用法?

时间:2016-07-08 10:07:48

标签: 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() {
    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未定义。为什么会这样?

4 个答案:

答案 0 :(得分:1)

多态性并不是这样的。由于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();

如何知道它应该调用哪个子类,因为它不是它的子方法。只有它自己的抽象方法,它知道孩子肯定会实现。

答案 1 :(得分:0)

a的类型为A,即使它指的是B的实例。

A没有Hello方法(即使是abstract声明)。所以你的编译器会发出错误。稍微调整代码

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

将是一个修复。 A然后假定接口的特征

答案 2 :(得分:0)

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.Hello()的引用变量调用B,那么它将对您有效。

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

public class C extends A {

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

    System.out.println("hello guys");
    }
    }

主要是像这样的声明

A a = new C();

如果您尝试拨打a.Hello(),那么Hello()方法会调用。编译器会感到困惑。

所以,这个概念只有在你试图覆盖子类中超类的方法时才有效。

答案 3 :(得分:0)

父类是否知道从中派生的类?

投射不会更改实际的对象类型。只有参考类型会被更改。

我强烈建议你从the link

写下我的上传和下传