1. Prerequisites for GObject Interface definition
If you want to specify that an interface requires the presence of other interfaces when implemented, GObject introduces the concept of prerequisites: You can associate a series of prerequisite types with an interface. For example, if object A wants to implement an interface I1, and if an interface I1 has a prerequisite that an interface I2 is required, a must implement I1 and I2.
The above mechanism is very similar in practice to the Java interface I1 extension interface I2:
/* Make the Viewereditablelossy interface require viewereditable interface. *
/G_define_interface (Viewereditablelossy, Viewer_editable_lossy, viewer_type_editable);
In the above G_define_interface call, the third parameter defines the precondition type. This is the gtype of the interface or class. In this case, the Viewereditable interface is a precondition for viewereditablelossy. The following code shows how the implementation implements the two interfaces and registers their implementations:
static void Viewer_file_editable_lossy_compress (Viewereditablelossy *editable) {viewerfile *self = Viewer_file (editab
Le);
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 = VI
ewer_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_edita
Ble_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 (Vi Ewerfile *self) {/* Instance variable initialisation code. */} G_define_type_with_code (Viewerfile, Viewer_file, g_ty
Pe_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))
It is important to note that the order in which the interface implementations are added to the main object is not random: the g_type_add_interface_static that calls G_implement_interface must first call an interface that has no other interface as a prerequisite.