你将学到什么

使用GObject模拟实现接口

使用接口

  • 首先按照学习笔记(一)定义一个普通的GObject类
  • 使用G_DEFINE_TYPE_WITH_CODEG_IMPLEMENT_INTERFACE替代G_DEFINE_TYPE来实现类定义
static void viewer_file_editable_interface_init (ViewerEditableInterface *iface);

G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
viewer_file_editable_interface_init))
  • 实现接口初始化函数viewer_file_editable_interface_init,接口内声明的每个虚函数指针都要被赋予实现
static void
viewer_file_editable_save (ViewerFile *self,
GError **error)
{
g_print ("File implementation of editable interface save method: %s.\n",
self->filename);
} static void
viewer_file_editable_undo (ViewerFile *self,
guint n_steps)
{
g_print ("File implementation of editable interface undo method: %s.\n",
self->filename);
} static void
viewer_file_editable_redo (ViewerFile *self,
guint n_steps)
{
g_print ("File implementation of editable interface redo method: %s.\n",
self->filename);
} static void
viewer_file_editable_interface_init (ViewerEditableInterface *iface)
{
iface->save = viewer_file_editable_save;
iface->undo = viewer_file_editable_undo;
iface->redo = viewer_file_editable_redo;
} static void
viewer_file_init (ViewerFile *self)
{
/* Instance variable initialisation code. */
}

扩展接口

如果一个接口的实现依赖另一个接口的实现,有点类似继承,那么首先按照上面的方式实现两个接口的定义,然后在定义GType的时候依次使用G_IMPLEMENT_INTERFACE添加两个接口的实现。

/* Make the ViewerEditableLossy interface require ViewerEditable interface. */
G_DEFINE_INTERFACE (ViewerEditableLossy, viewer_editable_lossy, VIEWER_TYPE_EDITABLE); static void
viewer_file_editable_lossy_compress (ViewerEditableLossy *editable)
{
ViewerFile *self = VIEWER_FILE (editable); g_print ("File implementation of lossy editable interface compress method: %s.\n",
self->filename);
} static void
viewer_file_editable_lossy_interface_init (ViewerEditableLossyInterface *iface)
{
iface->compress = viewer_file_editable_lossy_compress;
} static void
viewer_file_editable_save (ViewerEditable *editable,
GError **error)
{
ViewerFile *self = VIEWER_FILE (editable); g_print ("File implementation of editable interface save method: %s.\n",
self->filename);
} static void
viewer_file_editable_undo (ViewerEditable *editable,
guint n_steps)
{
ViewerFile *self = VIEWER_FILE (editable); g_print ("File implementation of editable interface undo method: %s.\n",
self->filename);
} static void
viewer_file_editable_redo (ViewerEditable *editable,
guint n_steps)
{
ViewerFile *self = VIEWER_FILE (editable); g_print ("File implementation of editable interface redo method: %s.\n",
self->filename);
} static void
viewer_file_editable_interface_init (ViewerEditableInterface *iface)
{
iface->save = viewer_file_editable_save;
iface->undo = viewer_file_editable_undo;
iface->redo = viewer_file_editable_redo;
} static void
viewer_file_class_init (ViewerFileClass *klass)
{
/* Nothing here. */
} static void
viewer_file_init (ViewerFile *self)
{
/* Instance variable initialisation code. */
} G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
viewer_file_editable_interface_init)
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE_LOSSY,
viewer_file_editable_lossy_interface_init))

接口属性

接口同样也可以拥有属性,不过是使用g_object_interface_install_property函数而不是像定义GType一样使用g_object_class_install_property函数来安装属性,如下所示:

static void
viewer_editable_default_init (ViewerEditableInterface *iface)
{
g_object_interface_install_property (iface,
g_param_spec_double ("autosave-frequency",
"Autosave frequency",
"Frequency (in per-seconds) to autosave backups of the editable content at Or zero to disable autosaves.",
0.0, /* minimum */
G_MAXDOUBLE, /* maximum */
0.0, /* default */
G_PARAM_READWRITE));
}

需要值得注意的一点是

重写接口方法

ViewerAudioFile继承自ViewerFile,两者都实现了ViewerEditable接口。ViewerAudioFile仅实现了ViewerEditable接口的其中一个方法,其他接口方法使用基类ViewerFile的实现,如下所示:

static void
viewer_audio_file_editable_save (ViewerEditable *editable,
GError **error)
{
ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable); g_print ("Audio file implementation of editable interface save method.\n");
} static void
viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface)
{
/* Override the implementation of save(). */
iface->save = viewer_audio_file_editable_save; /*
* Leave iface->undo and ->redo alone, they are already set to the
* base class implementation.
*/
} G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE,
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
viewer_audio_file_editable_interface_init)) static void
viewer_audio_file_class_init (ViewerAudioFileClass *klass)
{
/* Nothing here. */
} static void
viewer_audio_file_init (ViewerAudioFile *self)
{
/* Nothing here. */
}

在接口的default_init函数里面使用g_type_interface_peek_parent函数可以获取基类的接口实现,可将其保存到全局变量中供其他函数使用。下面的例子中,ViewerAudioFile重写了接口的save函数,并在重写函数中直接调用基类ViewerFile接口的save函数实现。

static ViewerEditableInterface *viewer_editable_parent_interface = NULL;

static void
viewer_audio_file_editable_save (ViewerEditable *editable,
GError **error)
{
ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable); g_print ("Audio file implementation of editable interface save method.\n"); /* Now call the base implementation */
viewer_editable_parent_interface->save (editable, error);
} static void
viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface)
{
viewer_editable_parent_interface = g_type_interface_peek_parent (iface); iface->save = viewer_audio_file_editable_save;
} G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE,
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
viewer_audio_file_editable_interface_init)) static void
viewer_audio_file_class_init (ViewerAudioFileClass *klass)
{
/* Nothing here. */
} static void
viewer_audio_file_init (ViewerAudioFile *self)
{
/* Nothing here. */
}

Glib学习笔记(四)的更多相关文章

  1. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  2. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  3. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  4. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  5. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  7. muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制

    目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...

  8. python3.4学习笔记(四) 3.x和2.x的区别,持续更新

    python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...

  9. Go语言学习笔记四: 运算符

    Go语言学习笔记四: 运算符 这章知识好无聊呀,本来想跨过去,但没准有初学者要学,还是写写吧. 运算符种类 与你预期的一样,Go的特点就是啥都有,爱用哪个用哪个,所以市面上的运算符基本都有. 算术运算 ...

  10. 零拷贝详解 Java NIO学习笔记四(零拷贝详解)

    转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...

随机推荐

  1. PHP5.6 安装Yaf 2.3.5

    Yaf 安装 PHP5.6 安装Yaf 2.3.5 1.下载 https://github.com/laruence/yaf 2.phpize /usr/bin/phpize 3.配置 ./confi ...

  2. 【OpenCV函数】轮廓提取;轮廓绘制;轮廓面积;外接矩形

    FindContours 在二值图像中寻找轮廓  int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_cont ...

  3. Android的按钮单击事件及监听器的实现方式

    第一种:匿名内部类作为事件监听器类 大部分时候,事件处理器都没有什么利用价值(可利用代码通常都被抽象成了业务逻辑方法),因此大部分事件监听器只是临时使用一次,所以使用匿名内部类形式 的事件监听器更合适 ...

  4. springboot成神之——spring的文件上传

    本文介绍spring的文件上传 目录结构 配置application DemoApplication WebConfig TestController 前端上传 本文介绍spring的文件上传 目录结 ...

  5. How To Install Git on CentOS 7

    Introduction Version control has become an indispensable tool in modern software development. Versio ...

  6. node.js开发指南读书笔记(1)

    3.1 开始使用Node.js编程 3.1.1 Hello World 将以下源代码保存到helloworld.js文件中 console.log('Hello World!'); console.l ...

  7. Java多线程-线程的调度(优先级)

    与线程休眠类似,线程的优先级仍然无法保障线程的执行次序.只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行. 线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先 ...

  8. ParksLink修改密码

    设置环境变量: ?set classpath=D:\ptc\PartsLink\srclib\jmxcore\WtLogR.jar;D:\ptc\PartsLink\srclib\log4j.jar; ...

  9. 【bzoj1024】[SCOI2009]生日快乐

    1024: [SCOI2009]生日快乐 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2372  Solved: 1717[Submit][Statu ...

  10. apt-get update 时的问题 W:Failed to fetch gzip:/var/lib/apt/lists/partial...解决办法

    http://askubuntu.com/questions/149454/upgrade-from-11-04-to-11-10-getting-wfailed-to-fetch-gzip 这个问题 ...