如果将方法覆盖在图片之外,那么您可以将Java类和方法视为一对C样式结构和一组对这些结构进行操作的函数.例如,如果您有这样的类:
public class MyJavaClass {
private int x;
public int getX() {
return x;
}
public int setX(int value) {
x = value;
}
}
这类似于为此效果编写C代码:
struct MyJavaClass {
int x;
};
int MyJavaClass_getX(struct MyJavaClass* this) {
return this->x;
}
void MyJavaClass_setX(struct MyJavaClass* this, int value) {
this->x = value;
}
主要思想是方法类似于将接收器对象作为隐式“this”参数的函数.在C中,您必须显式地将接收器作为参数传递给函数,而在Java中,这是通过object.method()语法隐式完成的.
如果您开始引入方法重写,这会变得有点复杂,因为您在对象上调用的方法取决于对象的动态类型,而不是静态类型.模拟这种情况的一种方法是使用称为vtable或虚函数表的东西,因为C的虚拟关键字而命名.这个想法是每个对象存储一个指向函数指针表的指针,每个函数可以被覆盖一个,当在对象上调用一个方法时,从表中选择适当的函数指针并调用它.所以,更恰当的是,上面的Java对象看起来像这样:
struct MyJavaClass_Vtable {
void (*getX)(struct MyJavaClass* this);
void (*setX)(struct MyJavaClass* this, int value);
};
struct MyJavaClass {
struct MyJavaClass_Vtable* vtable;
int x;
};
int MyJavaClass_getX(struct MyJavaClass* this) {
return this->x;
}
void MyJavaClass_setX(struct MyJavaClass* this, int value) {
this->x = value;
}
/* A global instance of the vtable for MyJavaClass */
struct MyJavaClass_Vtable MyJavaClassVtableInstance = {
&MyJavaClass_getX,
&MyJavaClass_setX
};
每当你创建一个MyJavaClass实例时,你都会设置它的vtable做这样的事情:
struct MyJavaClass* mjc = malloc(sizeof *mjc);
mjc->vtable = &MyJavaClassVtableInstance;
然后,在调用这样的函数时(在Java中):
myJavaClass.getX();
在C中它看起来像
myJavaClass->vtable->getX(myJavaClass);
所以从某种意义上说,Java类只是一个带有一些额外元信息的结构.当然,对于程序员来说,它看起来完全不同 – 有封装,多态,更严格的类型系统等等 – 但在本机代码级别,常规C结构和Java类可能看起来非常相似.
希望这可以帮助!