glib实践篇:接口定义与实现
前言:
在上一篇讲解了基于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实践篇:接口定义与实现的更多相关文章
- Java 8新特性-2 接口定义增强
为了解决当原有的接口中方法不足时,向原有的接口中添加新的方法,该接口下的N多实现类也需要重写该方法的问题!Java8引入了接口定义增强概念! Java8 打破了原有的接口的方法定义: 公共的.抽象的 ...
- java数据结构_附11_图的接口定义
图的接口定义 Graph public class UnsupportedOperation extends RuntimeException {public UnsupportedOperation ...
- [Asp.net 5] Configuration-新一代的配置文件(接口定义与基础实现)
关于配置文件的目录:[Asp.net 5] Configuration-新一代的配置文件 本系列文章讲的是asp.net 5(Asp.net VNext)中的配置文件部分,工程下载地址为:https: ...
- IOleItemContainer的接口定义
IOleItemContainer的接口定义
- IBindCtx接口定义
IBindCtx接口定义
- USB 3.0连接器引脚、接口定义及封装尺寸
上篇整理了USB 2.0A型.B型和Mini USB接口定义及封装,本文补充USB 3.0接口定义,USB 3.0采用的双总线结构,在速率上已经达到4.8Gbps,所以称为Super speed,在U ...
- USB 2.0 A型、B型、Mini和Micro接口定义及封装
USB全称Universal Serial Bus(通用串行总线),目前USB 2.0接口分为四种类型A型.B型.Mini型还有后来补充的Micro型接口,每种接口都分插头和插座两个部分,Micro还 ...
- 数据结构 链式哈希表(Hash Table)的接口定义与实现分析(完整代码)
链式哈希表的接口定义 关于哈希表与链式哈希表的描述可以参阅:http://www.cnblogs.com/idreamo/p/7990860.html 链式哈希表的操作与属性有:初始化.销毁.插入元素 ...
- 开地址哈希表(Hash Table)的接口定义与实现分析
开地址哈希函数的接口定义 基本的操作包括:初始化开地址哈希表.销毁开地址哈希表.插入元素.删除元素.查找元素.获取元素个数. 各种操作的定义如下: ohtbl_init int ohtbl_init ...
- CDN页面刷新接口定义[高升]
一 . 任务 分发 工作流程步骤 1. 合作方按照高升定义的 json 数据格式向高升分发接口 post 任务,高升分发接口会根据接收情况即时反馈接收成功还是失败的结果.二 . 高升 分发 接口 定义 ...
随机推荐
- 缓存,spring
applicationcontext.xml xmlns:cache="http://www.springframework.org/schema/cache" xsi:schem ...
- 分布式文件系统之MogileFS工作原理及实现过程
MogileFS是一套高效的文件自动备份组件,由Six Apart开发,广泛应用在包括LiveJournal等web2.0站点上.MogileFS由3个部分组成: 第1个部分:是server端,包 ...
- [置顶] 在js中如何实现方法重载?以及函数的参数问题
都知道在js中没有办法直接实现方法重载,因为在js中如果定义了多个名称相同,但参数个数不一样的方法,其实只有最后一个方法能被真正调用,其他的方法都被覆盖掉了. 但每一个函数都有一个特殊的参数argum ...
- exit与_exit
一.main函数: 先从程序的执行开始谈起,C程序总是从main函数开始执行,当内核执行C程序时(使用了一个exec函数),在调用main函数前先调用一个特殊的启动例程.可执行程序 文件将此启动例程指 ...
- java web项目基础
listener,filter,servlet的初始化顺序 web.xml中可以配置如下信息: context-param,listener,filter,servlet. 他们的加载顺序和在we ...
- C#类的初始化
类的构造函数 类的构造函数,有实例构造函数和静态构造函数.如果我们没有构造函数,系统会为我们生成一个默认构造函数,如果我们已经定义了构造函数,系统就不会再为我们生成构造函数. class Simp ...
- Oracle 10g数据库概述
一.Oracle 10g简介 1.Oracle 10g数据库是首个为网咯计算而设计的数据库(甲骨文公司的一款关系数据库管理系统). 2.分为以下几个版本: a.Oracle 10g数据库标准版 1 b ...
- [转]LLVM MC Project
Intro to the LLVM MC Project The LLVM Machine Code (aka MC) sub-project of LLVM was created to solve ...
- 【C#基础知识】静态构造函数,来源于一道面试题的理解
看到园友的一道面试题,很好奇,测试了一下结果. public class A { public static int X=B.Y ; public A() { ++X; } } public clas ...
- 大数据之HBase
大数据之HBase数据插入优化之多线程并行插入实测案例 一.引言: 上篇文章提起关于HBase插入性能优化设计到的五个参数,从参数配置的角度给大家提供了一个性能测试环境的实验代码.根据网友的反馈,基于 ...