Interface definition prerequisites

To specify that an interface requires the presence of other interfaces when implemented, GObject introduces the concept of prerequisites: it is possible to associate a list of prerequisite interfaces to an interface. For example, if object A wishes to implement interface I1, and if interface I1 has a prerequisite on interface I2, A has to implement both I1 and I2.

The mechanism described above is, in practice, very similar to Java's interface I1 extends interface I2. The example below shows the GObject equivalent:

  /* inside the GType function of the MamanIbar interface */
  type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbar", &info, 0);

  /* Make the MamanIbar interface require MamanIbaz interface. */
  g_type_interface_add_prerequisite (type, MAMAN_TYPE_IBAZ);

The code shown above adds the MamanIbaz interface to the list of prerequisites of MamanIbar while the code below shows how an implementation can implement both interfaces and register their implementations:

static void
maman_ibar_do_another_action (MamanIbar *ibar)
{
  MamanBar *self = MAMAN_BAR (ibar);

  g_print ("Bar implementation of IBar interface Another Action: 0x%x.\n",
           self->instance_member);
}

static void
maman_ibar_interface_init (MamanIbarInterface *iface)
{
  iface->do_another_action = maman_ibar_do_another_action;
}

static void
maman_ibaz_do_action (MamanIbaz *ibaz)
{
  MamanBar *self = MAMAN_BAR (ibaz);

  g_print ("Bar implementation of IBaz interface Action: 0x%x.\n",
           self->instance_member);
}

static void
maman_ibaz_interface_init (MamanIbazInterface *iface)
{
  iface->do_action = maman_ibaz_do_action;
}

static void
maman_bar_class_init (MamanBarClass *klass)
{

}

static void
maman_bar_init (MamanBar *self)
{
  self->instance_member = 0x666;
}

G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
                                                maman_ibaz_interface_init)
                         G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAR,
                                                maman_ibar_interface_init));

It is very important to notice that the order in which interface implementations are added to the main object is not random: g_type_add_interface_static, which is called by G_IMPLEMENT_INTERFACE, must be invoked first on the interfaces which have no prerequisites and then on the others.