BREW接口的继承特性应用
——目录——
引言
1、接口继承
2、实现继承
结语
引言
这里所说的BREW接口的继承特性,也就是BREW类的继承特性。一个BREW接口包括两部分,第一部分是接口的定义和接口函数宏的定义;第二部分是接口函数的实现。我往往把第一部分直接称为接口,所以“接口”二字有时表示的是一个独立完整的接口,有时指的是完整接口的第一部分。
从BREWapi里提供的接口来看,用到了两种继承方式:第一种,接口继承,这种继承方式下的基类类似C++里的虚基类,只有定义,没有实现,基类与子类之间的关系不是那么紧密,但又能达到很好的继承效果;第二种,实现继承,目前用到的实现继承基类有IApplet、IModule,这种继承与C++里的普通实现继承方式有些不一样,更像是实现扩展,C++里的普通实现继承方式在BREW接口里也是有能力做到的,但这是一个禁忌。
1、接口继承
每一个基类都要将其定义中的虚函数表define为一个继承宏,供子类使用。
1)所有BREW接口都是IBase的子类,都必需要实现IBase的两个接口函数。
IBase接口供子类使用的继承宏定义在AEEInterface.h里,
#define INHERIT_IBase(iname) /
uint32 (*AddRef) (iname*);/
uint32 (*Release) (iname*)
继承的方法是在子类的虚函数表的第一句写上: INHERIT_IBase(子类接口名);
2)所有控件类接口都是IControl的子类,
IControl接口的继承宏定义在AEE.h里
#define INHERIT_IControl(iname) /
INHERIT_IBase(iname);/
boolean (*HandleEvent) (iname *, AEEEvent evt, uint16 wParam, uint32 dwParam);/
boolean (*Redraw) (iname *);/
void (*SetActive) (iname *, boolean);/
boolean (*IsActive) (iname *);/
void (*SetRect) (iname *, const AEERect *);/
void (*GetRect) (iname *, AEERect *); /
void (*SetProperties) (iname *, uint32);/
uint32 (*GetProperties) (iname *); /
void (*Reset) (iname *)
每一个控件类接口的虚函数表的第一句为:INHERIT_IControl(控件接口名);由于INHERIT_IControl(iname)宏里也包含了对IBase的继承,所以不需要再写上INHERIT_IBase。
3)其它的继承都类似,在此不再多举。
下面以基类IBase的接口函数IBASE_Release(p)为例说明继承的用法。
每一个接口都有一个Release函数,这个函数就是通过INHERIT_IBase(iname)继承而来,拿002篇里的IStringParse接口来说,当使用完IStringParse的实例pIsp后,我们要调用IStringParse_Release(pIsp)来释放这个接口实例,由于这个接口函数是由IBase继承而来,所以我们调用IBase_Release(pIsp)也能达到同样的效果。为什么能做到?
我们看IBase_Release的定义:
#define IBASE_Release(p) GET_PVTBL(p,IBase)->Release(p)
实际是
#define IBASE_Release(p) ((IBase *)p->pvt)->Release(p)
将p强转为IBase接口,取其虚函数表指针pvt,然后触发虚函数表pvt里的函数指针Release。
由于IStringParse接口的虚函数表指针也叫pvt,并且虚函数表的第二个函数指针也叫Release,所以((IBase *)p->pvt)->Release(p)与((IStringParse *)p->pvt)->Release(p)的效果是一样的,也即IBASE_Release(pIsp)与IStringParse_Release(pIsp)的效果也是一样的。
所以,BREW接口继承的关键技术有2点:1)每一个接口的虚函数表指针的名称都一样(实现都为pvt);2)子类继承的虚函数指针名称必须与基类相同,并且在虚函数表中的位置必须一样。
2、实现继承
以IApplet为例,每一个applet都是对IApplet的继承,也可以说是扩展。在这种方式下,每一个applet并没有增加接口函数,也没有自已的接口定义和接口实现,只是对IApplet的实例结构体AEEApplet做了扩展,并且通过new函数AEEApplet_New注册了几个特定的处理函数。
这种继承方式要求基类要有自己的接口实现,能通过new函数给子类提供个性化的东西,并且要公开更多的东西。目前这种继承的用法不多。
结语
为了能轻松地理解接口继承,你必须对BREW接口有一个好的认识,《001[学习BREW] BREW的类机制.doc》、《002[学习BREW] 动手写BREW扩展接口.doc》能为你达到这个目的。为了能轻松地理解实现继承,你最好要看穿applet的本质,《003[学习BREW] applet的类特征.doc》能帮你达到这一点。当然,这些文章都只是差异化引导和深入,BREW官方文档还是基础,一定不要忘记。这里所说的差异是指与BREW官方文档的,官方文档里有的,我一般不写,也可以把这种差异理解为原创精神。