Gobject是单根继承的对象系统,但是通过interface也可以实现多继承。interface类似于C++中的抽象类,不能实例化但可以用来继承,类似U盘和移动硬盘,虽然本质上有所区别,但是它们的接口都是USB接口。并且只要它们插到计算机上,主机不关心那个东西是U盘还是移动硬盘,它只需要知道对方是个USB设备就可以了。这样,我们不需要在计算机主机中单独为U盘创造一种U盘接口,也不需要单独为移动硬盘创造一种移动硬盘接口。U盘和移动硬盘各自对USB接口进行适配所以USB接口并没有简化U盘和移动硬盘的设计而是简化了主机端的设计,interface也一样它不是用来搞代码复用以简化对象设计的,而是用来简化对象的上层建筑的设计。
头文件实现如下:
#ifndef _ANIMAL_ACTION_H_
#define _ANIMAL_ACTION_H_
#include
G_BEGIN_DECLS
#define ANIMAL_TYPE_ACTION animal_action_get_type()
G_DECLARE_INTERFACE(AnimalAction,animal_action,ANIMAL,ACTION,GObject)
struct _AnimalActionInterface
{
GTypeInterface parent_iface;
void (*run)(AnimalAction *self,char *pInfo);
void (*fly)(AnimalAction *self,char *pInfo);
};
void animal_action_run(AnimalAction* self,char *pInfo);
void animal_action_fly(AnimalAction* self,char *pInfo);
G_END_DECLS
#endif
宏
G_DECLARE_INTERFACE完成了如下工作:
(1)定义宏#define _AnimalActionInterface AnimalActionInterface和#define _AnimalAction AnimalAction
(2)定义类型转换宏ANIMAL_ACTION,类型检查宏ANIMAL_IS_ACTION,获取接口类型宏ANIMAL_ACTION_GET_IFACE
(3)根据您的先决条件类型为您的类型添加g_autoptr()支持。
实例类型AnimalAction没有被完全定义,它仅被用作一个抽象类型,最后是提供给外部函数调用的两个接口的声明。
源代码实现如下:
#include "animal-action.h"
G_DEFINE_INTERFACE(AnimalAction,animal_action,G_TYPE_OBJECT);
void animal_action_run(AnimalAction* self,char *pInfo)
{
AnimalActionInterface *iface = NULL;
g_return_if_fail(!(NULL == self || NULL == pInfo));
g_return_if_fail(ANIMAL_IS_ACTION(self));
iface = ANIMAL_ACTION_GET_IFACE(self);
g_return_if_fail(iface);
iface->run(self,pInfo);
}
void animal_action_fly(AnimalAction* self,char *pInfo)
{
AnimalActionInterface *iface = NULL;
g_return_if_fail(!(NULL == self || NULL == pInfo));
g_return_if_fail(ANIMAL_IS_ACTION(self));
iface = ANIMAL_ACTION_GET_IFACE(self);
g_return_if_fail(iface);
iface->fly(self,pInfo);
}
static void animal_action_default_init(AnimalActionInterface *iface)
{
iface->run = animal_action_run;
iface->fly = animal_action_fly;
printf("animal_action_default_init.\n");
}
G_DEFINE_INTERFACE宏默认调用接口初始化函数animal_action_default_init,接口方法animal_action_run和animal_action_fly直接调用接口回调函数。对象继承接口时可以用自己实现的函数覆盖此回调函数。
#ifndef _ABINAL_DOG_H_
#define _ABINAL_DOG_H_
#include "animal-base.h"
typedef struct _AnimalDog AnimalDog;
typedef struct _AnimalDogClass AnimalDogClass;
#define ANIMAL_TYPE_DOG (animal_dog_get_type())
//实例类型转换
#define ANIMAL_DOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ANIMAL_TYPE_DOG, AnimalDog))
//实例类型判定
#define ANIMAL_IS_DOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ANIMAL_TYPE_DOG))
//类结构转换
#define ANIMAL_DOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ANIMAL_TYPE_DOG, AnimalDogClass))
//类结构判定
#define ANIMAL_IS_DOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ANIMAL_TYPE_DOG))
//获取类结构
#define ANIMAL_DOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ANIMAL_TYPE_DOG, AnimalDogClass))
struct _AnimalDog
{
AnimalBase parent;
};
struct _AnimalDogClass
{
AnimalBaseClass classparent;
};
#endif
#include
#include "animal-dog.h"
#include "animal-action.h"
static void animal_action_interface_init(AnimalActionInterface *iface);
G_DEFINE_TYPE_WITH_CODE(AnimalDog,animal_dog,ANIMAL_TYPE_BASE,G_IMPLEMENT_INTERFACE(ANIMAL_TYPE_ACTION,animal_action_interface_init));
static void animal_action_interface_run(AnimalAction* self,char *pInfo)
{
printf("Dog[%p] info[%s] run...\n",ANIMAL_DOG(self),pInfo);
}
static void animal_action_interface_fly(AnimalAction* self,char *pInfo)
{
printf("Dogs[%p] info[%s] can not fly!\n",ANIMAL_DOG(self),pInfo);
}
static void animal_action_interface_init(AnimalActionInterface *iface)
{
printf("animal_action_interface_init.\n");
iface->run = animal_action_interface_run;
iface->fly = animal_action_interface_fly;
}
static void animal_dog_init(AnimalDog *pDog)
{
printf("animal_dog_init[%p].\n",pDog);
}
static void animal_dog_class_dispose(GObject *object)
{
printf("animal_dog_class_dispose.\n");
G_OBJECT_CLASS(animal_dog_parent_class)->dispose(object);
}
static void animal_dog_class_finalize(GObject *object)
{
printf("animal_dog_class_finalize.\n");
G_OBJECT_CLASS(animal_dog_parent_class)->finalize(object);
}
static void animal_dog_drink(AnimalBase *pBase)
{
printf("animal_dog_drink[%p][%p] class[%p][%p] AnimalDog[%p].\n",pBase,&(ANIMAL_DOG(pBase)->parent),ANIMAL_BASE_GET_CLASS(pBase),animal_dog_parent_class,ANIMAL_DOG(pBase));
}
static void animal_dog_eat(AnimalBase *pBase)
{
printf("animal_dog_eat[%p].\n",pBase);
}
static void animal_dog_run(AnimalBase *pBase)
{
printf("animal_dog_run[%p].\n",pBase);
}
static void animal_dog_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_properties)
{
printf("animal_dog_constructor.\n");
G_OBJECT_CLASS (animal_dog_parent_class)->constructor(type, n_construct_properties, construct_properties);
}
static void animal_dog_constructed (GObject *object)
{
printf("animal_dog_constructed.\n");
G_OBJECT_CLASS (animal_dog_parent_class)->constructed(object);
}
static void animal_dog_class_init(AnimalDogClass *pDogClass)
{
G_OBJECT_CLASS(pDogClass)->dispose = animal_dog_class_dispose;
G_OBJECT_CLASS(pDogClass)->finalize = animal_dog_class_finalize;
pDogClass->classparent.drinkwater = animal_dog_drink;
pDogClass->classparent.eat = animal_dog_eat;
pDogClass->classparent.run = animal_dog_run;
G_OBJECT_CLASS(pDogClass)->constructor = animal_dog_constructor;
G_OBJECT_CLASS(pDogClass)->constructed = animal_dog_constructed;
printf("animal_dog_class_init[%p].\n",pDogClass);
}
#include "animal-dog.h"
#include "animal-action.h"
int main (void)
{
AnimalDog *P0 = NULL;
AnimalDog *P1 = NULL;
AnimalDog *P2 = NULL;
g_type_init ();
P0 = g_object_new (ANIMAL_TYPE_DOG, NULL);
P1 = g_object_new (ANIMAL_TYPE_DOG, NULL);
P2 = g_object_new (ANIMAL_TYPE_DOG, NULL);
printf("start send signal.\n");
send_base_drink_signal(P0);
send_base_drink_signal(P1);
send_base_drink_signal(P2);
printf("end send signal.\n");
animal_action_run(P0,"111");
animal_action_fly(P0,"222");
g_object_unref(P0);
g_object_unref(P1);
g_object_unref(P2);
return 0;
}
运行结果如下: