Java虚方法调用有什么用?

时间:2012-07-11 10:59:04

标签: java oop virtual-method

我理解什么是java方法调用,并使用它练习了很多例子。

我想知道这个概念的实际情况或需要是什么。 如果有人能够提供一个真实世界的场景,那将是非常有用的 如果这个概念不存在会发生什么?

2 个答案:

答案 0 :(得分:16)

这是一个例子。假设我们有两个类:

class A {
    public String getName() {
        return "A";
    }
}

class B extends A {
    public String getName() {
        return "B";
    }
}

如果我们现在执行以下操作:

public static void main(String[] args) {
    A myA = new B();
    System.out.println(myA.getName());
}

我们得到结果

B

如果Java没有virtual method invocation,它将在编译时确定要调用的getName()是属于A类的myA。由于它没有,但在运行时根据Object指向的实际类来确定,我们得到上述结果。

[编辑添加(略设)示例]
您可以使用此功能编写一个方法,该方法将任意数量的public void printObjects(Object... objects) { for (Object o: objects) { System.out.println(o.toString()); } } s作为参数并打印出来,如下所示:

virtual method invocation

这适用于任何对象组合。如果Java没有toString(),则所有对象都将使用对象的toString()打印,而这些对象的可读性不高。现在,将使用每个实际类的{{1}},这意味着打印输出通常更具可读性。

答案 1 :(得分:1)

好的,我会尝试提供一个简单的例子。您正在编写一个方法来填充调用者提供的列表:

public void fill(List l) {
  list.add("I just filled the list!");
}

现在,一个来电者想要使用链表;另一个更喜欢基于数组的列表实现。将有其他呼叫者具有您从未听说过的更多列表实现。这些是完全不同的对象。提出一个解决方案,实现而不依赖于虚拟方法

如果没有虚拟方法,这意味着类型List已经需要实现方法add。即使您有一个具有重写方法的子类型ArrayList,编译器(和运行时!)也会忽略该方法并使用List中的方法。 不可能使用符合相同接口的不同List实现;在方法fill中重用该行代码是不可能的,因为它只适用于类型List中的方法。

所以你看,类型层次结构的整个想法并没有多大意义; interfaceabstract class甚至无法存在。如果没有虚拟方法的这一特性,整个Java都会分解成碎片。