方法“活着”在哪里?

时间:2010-10-05 04:10:02

标签: java

如果每个对象都有不同的实例变量副本,那么方法“生活吗?”

举个例子:

class A {
    public foo() {
        System.out.println("foo");
    }
}

class B extends A {
    public foo() {
        System.out.println("foofoo");
    }
}

public class Main {
    public static void main(String[] args) {
        A a = new B();
        a.foo(); // "foofoo"
    }
}

我知道印有“foofoo”字样。绑定到对象的方法是什么?

2 个答案:

答案 0 :(得分:4)

您所指的流程称为动态调度。通常通过虚拟表(通常称为vtable)实现此方法:

http://en.wikipedia.org/wiki/Virtual_table

vtable如何工作的简单总结是每个方法都存储在某个内存地址,而vtable存储这些地址。使用您的示例,A有一个vtable,其中的条目包含其foo版本的内存地址,而子类B有自己的vtable,具有相同的布局,但它改为保存自己的foo的内存地址。

答案 1 :(得分:3)

这通常是一个实施问题。作为Java程序员,您需要关心的是每个类可以使用与其他类不同的方法。

在实现方面(如果你对底层行为感兴趣),最简单的解决方案是让每个类都有一个指向所有相关函数的指针。

这样,当您使用A扩展B时,B类型的实例将获得所有A指向方法但指向{{1}的指针方法指针指向foo的代码。

B扩展B的图形表示,仅覆盖A

foo

类(对象)的实例知道它们的类型,因此您可以轻松地从对象class A foo ----------> Afoo code bar ----+-----> Abar code class B | bar ----+ foo ----------> Bfoo code 到类b。从那里,找到正确的代码运行是一个简单的操作。