GObject[5] 接口

1、接口不是用来搞代码复用以简化对象设计的,而是用来简化对象的上层建筑的设计。

2、接口的使用很简单,只要把一个类继承这个接口,然后实现接口中的方法。

3、接口的模拟大致分为三个部分:

  • 接口申明
  • 接口定义
  • 接口使用

4、接口的申明,以下代码(my-iusb.h)就申明了一个MyIUsb的接口,其实也和封装一个类差不多。

  • 实力结构体,空的就行。
  • 类结构体,里面第一句要指出父类是GTypeInstance,然后要指出方法的函数指针。
  • 接下来要先声明接口函数 
  • 注意一下接口的命名,My是项目缩写,I是interface的意思,IUSB是接口的名字
#ifndef MY_ISUB_H
#define MY_IUSB_H
/*********接口申明***********/
#include <glib-object.h>

#define MY_TYPE_IUSB (my_iusb_get_type())
#define MY_IUSB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MY_TYPE_IUSB,MyIUsb))
//MY_IS_IUSB可以识别某个对象是否属于obj指向的类型
#define MY_IS_IUSB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MY_TYPE_IUSB)

//这个宏用于从接口的实例结构体中取出类结构体的指针,具体怎么取得那就是GObject的事
#define MY_IUSB_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj),MY_TYPE_IUSB,MyIUsbInterface))


typedef struct _MyIUsb MyIUsb;  //实例结构体  My是项目缩写,USB是接口的名字,I代表interface

typedef struct _MyIUsbInterface MyIUsbInterface;
struct _MyIUsbInterface {   //类结构体
	GTypeInstance parent_interface;
	//这一组函数指针就是接口协议
	gchar *(*read)(MyIUsb *self); //read只能返回字符串
	void(*write)(MyIUsb *self, const gchar *str);//write只能写入字符串
};

GType my_iusb_get_type(void);

//声明接口,接口便是my_iusb_read, my_iusb_write
gchar *my_iusb_read(MyIUsb *self);
void my_iusb_write(MyIUsb *self, const gchar *str);

#endif // !MY_ISUB_H

 5、接口定义,在my-iusb.c里面定义接口。

  • g_return_if_fail(MY_IS_IUSB(self)) 在.h文件中定义了这个宏,用来检测对象是否是MY_IS_IUSB类型的
  • MY_IUSB_GET_INTERFACE(self) -> read(self) 用来从接口的实力结构体中取出类结构体的指针,具体怎么取的就不管啦
/**********接口的定义***********/
#include "my-iusb.h"

G_DEFINE_INTERFACE(MyIUsb, my_iusb, G_TYPE_INVALID); //与G_TYPE_TYPE类似,为类的实例化提供支持

//是G_DEFINE_INTERFACE宏的展开代码中申明的一个函数,里面可以放一些接口的初始化代码
static void my_iusb_default_init(MyIUsbInterface *iface) {

}

gchar * my_iusb_read(MyIUsb *self) {
	g_return_if_fail(MY_IS_IUSB(self));

	//MY_IUSB_GET_INTERFACE宏用于从MyIUsb接口的实例结构体中取出类结构体的指针,用这个指针就可以访问接口对应的方法啦
	MY_IUSB_GET_INTERFACE(self) -> read(self);
}

void my_iusb_write(MyIUsb *self, const gchar *str) {
	g_return_if_fail(MY_IS_IUSB(self)); // MY_IS_IUSB宏用来检测对象是否为MyIUsb类型,在.h文件中定义
	MY_IUSB_GET_INTERFACE(self)->write(self, self);

}

6、接口的使用

刚刚说接口的使用就是把一个类继承接口,然后实现这个接口的函数。所以可以在子类的.c文件里这样做:

  • 将接口添加到子类中
  • 具体定义接口函数
  • 表明子类实现了接口的函数
#include "my-udisk.h"
#include "my-iusb.h"
#include <stdio.h>

//以下函数的申明要在G_DEFINE_TYPE_WITH_CODE宏之前,因为这个宏展开代码中要用到这个函数
static void my_iusb_interface_init(MyIUsbInterface *iface);

//这个宏的作用:将接口添加到MyUdisk类中
G_DEFINE_TYPE_WITH_CODE (MyUdisk, my_udisk, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(MY_TYPE_IUSB, my_iusb_interface_init));

static gchar * my_udisk_read(MyIUsb *iusb) {
	MyUdisk *udisk = MY_UDISK(iusb);
	return udisk->data->str;
}

static void my_udisk_write(MyIUsb *iusb, const gchar *str) {
	MyUdisk *udisk = MY_UDISK(iusb);
	g_string_assign(udisk->data, str);
}

static void my_udisk_init(MyUdisk *self) {
	self->data = g_string_new(NULL);
}
static void my_udisk_class_init(MyUdiskClass *self) {

}

//表明MyUdisk类实现了MyIUsb所规定的接口
static void my_iusb_interface_init(MyIUsbInterface *iface) {
	iface->read = my_udisk_read;
	iface->write = my_udisk_write;
}

参考http://garfileo.is-programmer.com/2011/3/15/inheritance-and-interface.25299.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值