Implementing interfaces: GObject Reference Manual

## Implementing interfaces

Once the interface is defined, implementing it is rather trivial.

The first step is to define a normal final GObject class exactly as in the section called “Boilerplate header code”.

The second step is to implement ViewerFile by defining it using `G_DEFINE_TYPE_WITH_CODE` and `G_IMPLEMENT_INTERFACE` instead of `G_DEFINE_TYPE`:

    1
    2
    3
    4
    5
    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))

This definition is very much like all the similar functions seen previously. The only interface-specific code present here is the use of `G_IMPLEMENT_INTERFACE`.

Classes can implement multiple interfaces by using multiple calls to `G_IMPLEMENT_INTERFACE` inside the call to `G_DEFINE_TYPE_WITH_CODE`

`viewer_file_editable_interface_init`, the interface initialization function: inside it every virtual method of the interface must be assigned to its implementation:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    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. */
    }

If the object is not of final type, e.g. was declared using `G_DECLARE_DERIVABLE_TYPE` then `G_ADD_PRIVATE` macro should be added. The private structure should be declared exactly as for a normal derivable object, see the section called “Boilerplate code”.

    1
    2
    3
    4
    G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
                             G_ADD_PRIVATE (ViewerFile)
                             G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
                                                    viewer_file_editable_interface_init))