前言:

  在上一篇讲解了基于glib实现抽象和继承后,当然这篇就得讲讲接口类型啦!

  在JAVA中接口更多的弥补了其单继承所带来的缺陷,使其能够扩展很多功能,同时又不破坏它的结构。其实接口就是一种协议,在A类不能直接调用B类方法、尽量降低耦合性和避免杂糅混乱等情况下便可以使用接口来建立之间的联系。同样,本篇以一个简单的C语言例子来进行接口的实现。

开发环境:

  eclipse集成开发环境、glib库、ubuntu操作系统。

设计流程:

  1、定义一个test接口类,定义4个接口方法

  2、定义一个test类实现这个接口,执行结果就是打印4个方法的命名

  3、主函数调用接口测试

以下是类的设计:

  test接口类:
  testhandler.h

 #ifndef __TEST_HANDLER_H__
#define __TEST_HANDLER_H__ #include <glib-object.h>
#include<glib.h>
G_BEGIN_DECLS #define TYPE_TEST_HANDLER (test_handler_get_type())
#define TEST_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_TEST_HANDLER, TestHandlerInterface))
#define IS_TEST_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_TEST_HANDLER))
#define TEST_HANDLER_INTERFACE(klass) ((TestHandlerInterface*)g_type_interface_peek((klass), TYPE_TEST_HANDLER))
#define GET_TEST_HANDLER_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_TEST_HANDLER, TestHandlerInterface)) typedef struct _TestHandlerInterface TestHandlerInterface; struct _TestHandlerInterface
{
GObjectClass parent_iface; void (*start)(TestHandlerInterface *self);
void (*pause)(TestHandlerInterface *self);
void (*resume)(TestHandlerInterface *self);
void (*stop)(TestHandlerInterface *self);
};
GType test_handler_get_type(void); G_END_DECLS
#endif /* _TEST_HANDLER_H_ */

  testhandler.c

 #include "testhandler.h"

 /************ defines ************/
G_DEFINE_INTERFACE(TestHandler, test_handler, G_TYPE_OBJECT) static void test_handler_default_init(TestHandlerInterface *iface)
{ }

  test类(实现接口的类):

  test.h

 #ifndef __TEST_H__
#define __TEST_H__ #include <glib-object.h> G_BEGIN_DECLS #define TYPE_TEST (test_get_type())
#define TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_TEST, Test))
#define TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_TEST, TestClass))
#define IS_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_TEST))
#define IS_TEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_TEST))
#define GET_TEST_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TEST, TestClass)) /************ types ************/
typedef struct _Test Test;
typedef struct _TestClass TestClass;
typedef struct _TestPrivate TestPrivate; struct _Test
{
GObject parent;
};
struct _TestClass
{
GObjectClass parent_class;
}; /************ globals ************/ /************ function declarations ************/
GType test_get_type(void); G_END_DECLS
#endif /* _TEST_H_ */

  test.c 

 #include"test.h"
#include"testhandler.h" /************ defines ************/
static void test_handler_interface_init(TestHandlerInterface *iface);
G_DEFINE_TYPE_WITH_CODE(Test, test, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(TYPE_TEST_HANDLER, test_handler_interface_init))
#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_TEST, TestPrivate)) /************ types ************/
struct _TestPrivate
{ };
/************ function declarations ************/ static void dispose_od(GObject *object);
static void finalize_od(GObject *object);
void start_od(TestHandlerInterface *self);
void pause_od(TestHandlerInterface *self);
void resume_od(TestHandlerInterface *self);
void stop_od(TestHandlerInterface *self);
/************ function implements ************/ static void test_class_init(TestClass *klass)
{
GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
g_type_class_add_private(g_object_class, sizeof(TestPrivate));
g_object_class->dispose = dispose_od;
g_object_class->finalize = finalize_od; } static void test_handler_interface_init(TestHandlerInterface *iface)
{
TestHandlerInterface *testHandlerIface = iface;
testHandlerIface->start=start_od;
testHandlerIface->pause=pause_od;
testHandlerIface->resume=resume_od;
testHandlerIface->stop=stop_od;
} static void test_init(Test *self)
{
TestPrivate *priv = GET_PRIVATE(self);
} static void dispose_od(GObject *object)
{
Test *self = (Test*) object;
TestPrivate *priv = GET_PRIVATE(self);
// 释放创建的对象
G_OBJECT_CLASS(test_parent_class)->dispose(object);
} static void finalize_od(GObject *object)
{
Test *self = (Test*) object;
TestPrivate *priv = GET_PRIVATE(self);
// 释放创建的内存
G_OBJECT_CLASS(test_parent_class)->finalize(object);
} void start_od(TestHandlerInterface *self)
{
TestPrivate *priv = GET_PRIVATE(self);
g_print("start_od!\n");
}
void pause_od(TestHandlerInterface *self)
{
TestPrivate *priv = GET_PRIVATE(self);
g_print("pause_od!\n");
}
void resume_od(TestHandlerInterface *self)
{
TestPrivate *priv = GET_PRIVATE(self);
g_print("resume_od!\n");
}
void stop_od(TestHandlerInterface *self)
{
TestPrivate *priv = GET_PRIVATE(self);
g_print("stop_od!\n");
}

  主函数:

 #include<glib.h>
#include<stdio.h>
#include<stdlib.h>
#include"test.h"
#include"testhandler.h"
#include<string.h>
int main(void)
{
Test *test = g_object_new(TYPE_TEST,NULL);
if (test != NULL)
{
GET_TEST_HANDLER_INTERFACE(test)->start(TEST_HANDLER(test));
GET_TEST_HANDLER_INTERFACE(test)->pause(TEST_HANDLER(test));
GET_TEST_HANDLER_INTERFACE(test)->resume(TEST_HANDLER(test));
GET_TEST_HANDLER_INTERFACE(test)->stop(TEST_HANDLER(test));
}
return EXIT_SUCCESS;
}

总结:

  从主函数中的测试代码中我们可以看出,调用接口的一方或类还是需要联系接口方法的实现类,耦合度还是较高,而在JAVA中接口则能够很好的分离两方。所以在C语言中接口主要是用于上层结构设计,同时由于gobject并未

能很好的实现接口,所以在项目中为了是两者很好的分离,其中一个办法就是通过指针调用来尽量做到低耦合,例如使用重载等方法。

glib实践篇:接口定义与实现的更多相关文章

  1. Java 8新特性-2 接口定义增强

    为了解决当原有的接口中方法不足时,向原有的接口中添加新的方法,该接口下的N多实现类也需要重写该方法的问题!Java8引入了接口定义增强概念! Java8 打破了原有的接口的方法定义: 公共的.抽象的  ...

  2. java数据结构_附11_图的接口定义

    图的接口定义 Graph public class UnsupportedOperation extends RuntimeException {public UnsupportedOperation ...

  3. [Asp.net 5] Configuration-新一代的配置文件(接口定义与基础实现)

    关于配置文件的目录:[Asp.net 5] Configuration-新一代的配置文件 本系列文章讲的是asp.net 5(Asp.net VNext)中的配置文件部分,工程下载地址为:https: ...

  4. IOleItemContainer的接口定义

      IOleItemContainer的接口定义

  5. IBindCtx接口定义

    IBindCtx接口定义

  6. USB 3.0连接器引脚、接口定义及封装尺寸

    上篇整理了USB 2.0A型.B型和Mini USB接口定义及封装,本文补充USB 3.0接口定义,USB 3.0采用的双总线结构,在速率上已经达到4.8Gbps,所以称为Super speed,在U ...

  7. USB 2.0 A型、B型、Mini和Micro接口定义及封装

    USB全称Universal Serial Bus(通用串行总线),目前USB 2.0接口分为四种类型A型.B型.Mini型还有后来补充的Micro型接口,每种接口都分插头和插座两个部分,Micro还 ...

  8. 数据结构 链式哈希表(Hash Table)的接口定义与实现分析(完整代码)

    链式哈希表的接口定义 关于哈希表与链式哈希表的描述可以参阅:http://www.cnblogs.com/idreamo/p/7990860.html 链式哈希表的操作与属性有:初始化.销毁.插入元素 ...

  9. 开地址哈希表(Hash Table)的接口定义与实现分析

    开地址哈希函数的接口定义 基本的操作包括:初始化开地址哈希表.销毁开地址哈希表.插入元素.删除元素.查找元素.获取元素个数. 各种操作的定义如下: ohtbl_init int ohtbl_init ...

  10. CDN页面刷新接口定义[高升]

    一 . 任务 分发 工作流程步骤 1. 合作方按照高升定义的 json 数据格式向高升分发接口 post 任务,高升分发接口会根据接收情况即时反馈接收成功还是失败的结果.二 . 高升 分发 接口 定义 ...

随机推荐

  1. tortoiseSVN 设置ignore

      *.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store *.dll ...

  2. SSL协议的握手过程

    SSL握手的目的 第一,客户端与服务器需要就一组用于保护数据的算法达成一致. 第二,它们需要确立一组由那些算法所使用的加密密钥. 第三,握手还可以选择对客户端进行认证. SSL 握手概述 SSL 握手 ...

  3. [转]ARM/Thumb2PortingHowto

    src: https://wiki.edubuntu.org/ARM/Thumb2PortingHowto#ARM_Assembler_Overview When you see some assem ...

  4. 判断UA这种事不能说的太明。

    [微博] Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; GT-I9502 Build/JDQ39) AppleWebKit/534.30 (KHTML, l ...

  5. 微软RDLC报表打印

    关于微软RDLC报表打印时文字拉伸问题(Windows server 2003 sp2) 最近我们开发的打印服务频频出现打印文字拉伸问题,客户意见络绎不绝,最为明显的是使用黑体加粗后 “2.0份” 打 ...

  6. 软件Scrum

    软件海贼团 OnePiece (版权所有) 最近迷上了“海贼王”这部动画片,不仅仅是因为其中的人物个个性格鲜明,剧情跌宕起伏扣人心弦,各种耍宝搞笑,还感觉到这个团队很像理想中的敏捷软件团队. 作为一直 ...

  7. Jquery 类似新浪微博,鼠标移到头像,用浮动窗口显示用户信息,已做成一个jquery插件

    请注意!!!!! 该插件demo PHP 的 demo下载  C#.NET的demo下载 需要如下图, 1.鼠标移动到头像DIV时,Ajax获取数据,并让浮动DIV显示出来. 2.鼠标可以移动到上面浮 ...

  8. 开发win8 metro monogame,显示pubcenter广告时会使游戏卡住的问题的解决方法。

    开发win8 metro游戏,使用monogame,并且还加上pubcenter广告,但是在x64的机子上遇到了问题,广告一出,游戏卡死.经过一系列的判断,发现monogame一直在update和dr ...

  9. MacOSX 下.app支持同时运行多个实例

    在MacOSX下的.app是一个程序包(实际上是个目录),双击该目录时系统会根据包的目录结构启动相应的可执行程序..app的程序默认是单实例运行的,所以从.app启动的程序实例只有一个(可执行程序不受 ...

  10. 如何让msvsmon.exe 以服务方式运行

    通常我们在VS上调试程序用的都是msvsmon.exe, 使用管理员权限运行再选项设置任何人可以调试就可以了,而这个在绝大多数情况下都没有问题.而我想说的就是特殊的情况,跟msvsmon的运行权限相关 ...