Interface编程实现

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;  
}  

运行结果如下:

Interface编程实现_第1张图片

你可能感兴趣的:(Gobject)