你将学到什么

使用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. Py修行路 python基础(六)前期基础整理

    计算机中,有且仅有CPU具有执行权限,能够执行指令的只有CPU! 人在应用程序上输入的文字或文本,叫做明文! 在屏幕上输入或是输出的是字符,计算机保存的是 有字符编码的 二进制数. 变量赋值规则:例如 ...

  2. Py修行路 python基础 (九)作用域 函数嵌套 闭包

    名称空间与作用域 变量,函数 分成三种 #内置名称空间  内置函数, 系统函数内部自定义的. python查看内置函数,命令: import builtins dir(builtins) #全局名称空 ...

  3. Python多线程-生产者消费者模型

    用多线程和队列来实现生产者消费者模型 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import threading imp ...

  4. linux下的定时或计时操作(gettimeofday等的用法,秒,微妙,纳秒(转载)

    一.用select()函数实现非阻塞时的等待时间,用到结构体struct timeval {},这里就不多说了. 二.用gettimeofday()可获得微妙级(0.000001秒)的系统时间,调用两 ...

  5. Android studio如何和VS的region一样折叠代码

    相信用过VS的朋友都会经常有用到VS的region来折叠代码,非常方便.那么Android studio是否可以呢?当然可以. 选择代码,Ctrl + Alt + T 选择 第二项,这样就可以啦

  6. Python基础学习三 字典、元组

    一.元组 元组,提示别人,这个值是不能被改变的,元组的定义方式是用(),小括号: 元组只有两个方法,那就是count和index mysql1 = ('127.0.0.1',3306,'my','ro ...

  7. python数据字典的操作

    一.什么是字典? 字典是Python语言中唯一的映射类型. 映射类型对象里哈希值(键,key)和指向的对象(值,value)是一对多的的关系,通常被认为是可变的哈希表. 字典对象是可变的,它是一个容器 ...

  8. mysql如何进行以=分割的字符串的拆分

    SUBSTRING_INDEX(str, delim, count) str: 要处理的字符串 delim: 分割符 count: 计数 如果为正数,则从左开始数,如果为负数,则从右开始数 使用示例: ...

  9. 把List<string>转为DataTable

    //把List<string>转为DataTable List<string> myList = new List<string>(); DataTable dt2 ...

  10. RichEdit在Win8上乱码

    之前的一个项目中使用了RichEdit,发现在Win8中输入中文乱码,但是复制粘贴正常. 经过各种搜索调查,发现是msftedit.dll的问题,我在win7上找到msftedit.dll,将它拷贝到 ...