如果每个对象都有不同的实例变量副本,那么方法“生活吗?”
举个例子:
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”字样。绑定到对象的方法是什么?
答案 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
。从那里,找到正确的代码运行是一个简单的操作。