上一篇文章有说到,在Android中的每一个类,在内存中都是以ClassObject结构体来表示的。而类的每个方法都是以Method结构体来表示的。具体可看源码中的 Object.h
在 ClassObject 中有下面几个变量和今天的题目有关:
ClassObject* super;
指向父类的结构体指针
int interfaceCount;
ClassObject** interfaces;
继承的接口类个数,及接口类的地址数组
/* static, private, and
methods */
int directMethodCount;
Method* directMethods;
静态方法、私有方法、构造方法的总个数及方法数组
/* virtual methods defined in this class; invoked through vtable */
int virtualMethodCount;
Method* virtualMethods;
本类的虚方法总个数及方法数组
int vtableCount;
Method** vtable;
本类及继承树中所有的虚方式总个数及方法数组
int iftableCount;
InterfaceEntry* iftable;
本类继承的接口个数及,接口表数组。
写如下类:
public interface ClsInterface {
abstract void TestFunc();
}
public class ClsA implements ClsInterface {
@Override
public void TestFunc() {
Log.v("NNNN", "ClsA-TestFunc");
}
public void AFunc() {
Log.v("NNNN", "ClsA-AFunc");
}
}
public class ClsA1 extends ClsA {
@Override
public void AFunc() {
super.AFunc();
Log.v("NNNN", "ClsA1-AFunc");
}
public void A1Func() {
Log.v("NNNN", "ClsA1-A1Func");
}
}
对内存进行分析一下:
ClsInterface 对像:
- 父类指向还是Object
- virtualMethodCount 为1
- virtualMethod 有一个方法,是JNI实现,实现函数dvmAbstractMethodStub
- dvmAbstractMethodStub目地是报出异常(该函数没有实现)
- 其它变量为空
ClsA 对像:
- 父类指向还是Object 而非接口类。
- interfaceCount 为1,代表继承了一个接口类
- interfaces 有值
- directMethod 会增加一个 <init> 方法,用于构造类。
- virtualMethod 会有二个方法,即 TestFunc、AFunc
- vtable 会有 13 个方法,其中 11 为 Object 继承过来的方法(wait, notify, toString 等),二个为 TestFunc AFunc
- iftable 会有 1 个,指向 ClsInterface
ClsA1 对像:
- 父类指向 ClsA
- interface 为 0,即没有直接继承接口类。
- directMethod 还是1个,即<init>
- virtualMethod 2 个, AFunc A1Func
- vtable 14 个, 其中 11 为 Object 的。其它 3 个方法 AFunc A1Func TestFunc
- TestFunc 方法是继承来的,所以地址指向的是 ClsA 中的方法地址。
- iftable 还会 1 个,指向 ClsInterface
通过测试,大楖明白了在C++中是如何通过内存数据来实现Android中的Java类继承。