# Multiple Class Inheritance with Eolian #

The [previous tutorial](eo-inherit.md) showed you how a new class can be created by inheriting from an already existing *base class*. Like many other programming languages Eolian also allows inheriting from more than one place at the same time, with certain restrictions.

This tutorial explains the special kinds of classes that Eolian offers to allow trouble-free multiple inheritance: *interfaces* and *mixins*.

## Prerequisites ##

* This tutorial builds on top of the classes developed in [Class Inheritance with Eolian](eo-inherit.md).

## The Risks of Multiple Class Inheritance ##

Allowing a class to have more than one parent has some caveats, such as the well-known *diamond problem*. Suppose a class ``Parent`` has a method, overridden in different ways by its two children ``Child1`` and ``Child2``, then a new class ``Grandchild`` inherits from both ``Child1`` and ``Child2`` and calls that method. Which implementation should be actually called?

C++, for example, allows you to create such hierarchies but forces you to specify which implementation you want to use in ambiguous cases. Most languages however solve the diamond problem by imposing restrictions on the classes from which you can inherit. These restrictions remove the possibility of ambiguous hierarchies and result in arguably cleaner code.

Eolian (and [other languages](https://en.wikipedia.org/wiki/Mixin#Programming_languages_that_use_mixins)) defines two new kinds of classes, *interfaces* and *mixins* and imposes some inheritance rules:

1. You can only *inherit* from one *regular* class, which is indicated with the ``extends`` keyword.

2. You can *implement* as many *interfaces* as you want, listing them after the ``implements`` keyword.

3. You can *include* as many *mixins* as you want, listing them after the ``implements`` keyword.

*Inherit*, *implement* and *include* all mean *use functionality from a parent class*. Using a different word for each kind of parent class helps keep ambiguity to a minimum.

Interfaces are like classes but they only define methods and contain no implementation. Mixins are classes which contain implementations but they cannot be inherited from, only included. Neither one can be instantiated on its own: they are meant to be implemented or included.

The following steps will clarify these concepts.

## Step One: Copying the Code from the Previous Tutorial ##

This tutorial builds on top of the previous one ([Class Inheritance with Eolian](eo-inherit.md)), so begin by creating a copy of all your existing code to a new folder.

Next rename the main file ``eo_inherit_main.c`` to ``eo_multiinherit_main.c`` to maintain consistency with the name of this tutorial.

## Step Two: Merging the Includes ##

As you have already learned, the header file for each new class needs to be included in each file that uses that class. In this example you are going to add several classes and objects to the hierarchy created in the previous tutorial, which means a lot of new header files need to be tracked.

A common practice to simplify this situation is to include all header files from a new file, then use only the new file. To this end, create a new file called ``eo_multiinherit.h``:

```c #include “example_rectangle.eo.h” #include “example_square.eo.h” ```

Now use:

```c #include “eo_multiinherit.h” ```

Do this instead of ``example_rectangle.eo.h`` and ``example_square.eo.h`` in all implementation files.

You can now build and run your program to check that everything still works as expected.

## Step Three: Defining an Interface ##

Interfaces are like classes but do not contain any implementation, only contain method definitions. When a class *implements* an interface (another way of saying that the class inherits from the interface) it is agreeing to provide the implementation for the missing methods. In this way, the interface methods can be called on different unrelated classes, as long as they all implement the interface.

You are now going to define a new interface in Eolian, which will be implemented by the ``Example.Rectangle`` class. It does not make much sense to use an interface when only one class is implementing it but you'll define more in the next steps.

The interface will be called ``Example.Shape`` and will only define the method ``area()`` which previously was part of the ``Example.Rectangle`` class.

Create the ``example_shape.eo`` file and write its contents:

``` interface Example.Shape {

 methods {
    area {
       params {
       }
       return: int;
    }
 }

} ```

As you can see the interface is declared with the keyword ``interface`` instead of ``class`` as you did for the other classes. The rest of the file should already be familiar to you. It contains a ``methods`` block which defines only one method called ``area()``.

Next, turn this Eolian file into C code with ``eolian_gen``. Note that since interfaces do not contain implementations, you do not need to generate an implementation file i.e. you could use the ``-gch`` switch instead of ``-gchi`` to avoid generating ``example_shape.c``.

If you did do this, you'd have to include the boilerplate C file ``example_shape.eo.c`` in your build instead of the usual implementation file ``example_shape.c``. For consistency, generate the implementation file. It will only contain the boilerplate C file in any case:

```bash eolian_gen -gchi example_shape.eo ```

Now edit the includes file ``eo_multiinherit.h`` and add the newly generated ``example_shape.eo.h`` after the other includes:

```c #include “example_shape.eo.h” ```

## Step Four: Implementing the Interface ##

Tell ``Example.Rectangle`` that it will be implementing the new ``Example.Shape`` interface. Open the ``example_rectangle.eo`` file, then:

* Add ``implements Example.Shape`` after ``extends Efl.Object`` at the top of the file.

* Remove all lines in the ``area { … }`` block.

* Add a new block after the closing brace of the ``methods`` block:

```
   implements {
    Example.Shape.area;
   }
```

This tells Eolian that the ``Example.Rectangle`` class is going to implement the ``area()`` method from the ``Example.Shape`` interface instead of providing its own.

The completed file should look like this:

``` class Example.Rectangle extends Efl.Object implements Example.Shape {

 methods {
    @property width {
       set {
       }
       get {
       }
       values {
          width: int;
       }
    }
    @property height {
       set {
       }
       get {
       }
       values {
          height: int;
       }
    }
 }
 implements {
    Example.Shape.area;
 }

} ```

Run ``eolian_gen`` again to obtain the C code:

```bash eolian_gen -gchi example_rectangle.eo -I . ```

Pay careful attention to the ``-I`` switch so it can find the new class you are now including.

``eolian_gen`` will add any missing methods to your already existing implementation file ``example_rectangle.c`` but it will not remove existing methods which are no longer needed.

This means that in the implementation file you will now find:

* An empty method where you must put the implementation for ``Example.Shape.area()``: ``_example_rectangle_example_shape_area()``.

* Your previous implementation of the ``Example.Rectangle.area()`` method: ``_example_rectangle_area()``.

Simply move the one-line implementation (``return pd->width * pd->height;``) from the old method to the new one, then completely remove the old one.

It might look like not much has changed but the area method is now available through an interface, which means that all classes implementing it (including ``Example.Rectangle`` and its descendants) can be handled in a similar manner.

## Step Five: Using the Interface ##

Since you removed the ``area()`` method from ``Example.Rectangle``, the main program will not work anymore. However since ``Example.Rectangle`` now implements the ``Example.Shape`` interface, you can use its methods, including ``area()``.

Replace both uses of ``example_rectangle_area()`` with ``example_shape_area()``.

NOTE:
At this point the ``_rectangle_create()`` and ``_square_create()`` methods can return their respective types or an ``Example_Shape *`` (or even an ``Eo *`` as seen in the [Introduction to Eo](eo-intro) tutorial).

Now build and run the program. Remember to include the new source file ``example_shape.c``:

```bash gcc eo_multiinherit_main.c example_rectangle.c example_square.c example_shape.c `pkg-config –cflags –libs elementary` ```

Upon execution your terminal should display the same message as at the end of the previous tutorial:

``` Rectangle is 5×10, area is 50 Square is 7×7, area is 49 ```

## Step Six: Adding Another Class ##

In order to demonstrate the usefulness of the interface once and for all, you'll now add another class unrelated to ``Example.Rectangle`` or ``Example.Square`` but implementing the same ``Example.Shape`` interface.

Start by creating a new Eolian file called ``example_circle.eo``:

``` class Example.Circle extends Efl.Object implements Example.Shape {

 methods {
    @property radius {
       set {
       }
       get {
       }
       values {
          radius: int;
       }
    }
 }
 implements {
    Example.Shape.area;
 }

} ```

This looks a lot like ``example_rectangle.eo`` but it defines a class named ``Example.Circle``, which has a ``radius`` property (instead of ``width`` and ``height``). It also implements the ``area()`` method from the ``Example.Shape`` interface.

Now turn this file into C code with ``eolian_gen``:

```bash eolian_gen -gchi example_circle.eo -I . ```

Add the new header file ``example_circle.eo.h`` to ``eo_multiinherit.h``:

```c #include “example_circle.eo.h” ```

Next add the implementation for the new class. Edit ``example_circle.c`` then:

* Replace the automatically generated ``#include “example_circle.eo.h“`` with ``#include “eo_multiinherit.h“``

* Inside the ``Example_Circle_Data`` structure add a variable to hold the radius of the circle: ``int radius;``

* Add the implementation for the setter: ``pd->radius = radius;``

* Add the implementation for the getter: ``return pd->radius;``

* Add the implementation for the ``area()`` interface method: ``return (int)(pd->radius * pd->radius * 3.14159f);``

After adding some ``EINA_UNUSED`` to the unused method parameters the implementation file should look like this:

```c #define EFL_BETA_API_SUPPORT #include <Eo.h> #include “eo_multiinherit.h”

typedef struct {

 int radius;

} Example_Circle_Data;

EOLIAN static void _example_circle_radius_set(Eo *obj EINA_UNUSED, Example_Circle_Data *pd, int radius) {

 pd->radius = radius;

}

EOLIAN static int _example_circle_radius_get(const Eo *obj EINA_UNUSED , Example_Circle_Data *pd) {

 return pd->radius;

}

EOLIAN static int _example_circle_example_shape_area(Eo *obj EINA_UNUSED, Example_Circle_Data *pd) {

 return (int)(pd->radius * pd->radius * 3.14159f);

}

#include “example_circle.eo.c” ```

The next step instantiates this new class to check that everything works as expected.

## Step Seven: Using the New Class ##

Start by adding the method that will instantiate the new class. You should already be familiar with all the required bits:

```c Example_Circle * _circle_create() {

 Example_Circle *circle;
 circle = efl_new(EXAMPLE_CIRCLE_CLASS,
                  efl_name_set(efl_added, "Circle"),
                  example_circle_radius_set(efl_added, 5));
 return circle;

} ```

You'll now make use of the fact that all instantiated shapes implement the ``Example.Shape`` interface and remove the duplicated ``printf()`` calls. Create a new method that will take care of printing:

```c void _shape_print(Example_Shape *shape) {

 printf("Shape named %s has area %d\n",
        efl_name_get(shape), example_shape_area(shape));

} ```

Notice how it receives an ``Example_Shape *`` and uses methods from that interface (and from ``Efl_Object``, like ``efl_name_get()``). This method will not be able to print the ``width`` and ``height`` of the rectangles as before since it now receives shapes which might not be rectangular.

Next replace the entire content of ``efl_main()``:

```c

 Eo *shape;
 shape = _circle_create();
 _shape_print(shape);
 efl_unref(shape);
 shape = _rectangle_create();
 _shape_print(shape);
 efl_unref(shape);
 shape = _square_create();
 _shape_print(shape);
 efl_unref(shape);
 efl_exit(0);

```

As you can see handling the different shapes is now much simpler through the common interface.

Now build and run the program (remember to include ``example_circle.c`` in the mix):

```bash gcc eo_multiinherit_main.c example_rectangle.c example_square.c example_shape.c example_circle.c `pkg-config –cflags –libs elementary` ```

You should see the following in the terminal:

``` Shape named Circle has area 78 Shape named Rectangle has area 50 Shape named Square has area 49 ```

This concludes the part regarding interfaces. The next steps demonstrate usage of mixins.

## Step Eight: Defining a Mixin ##

Mixins are meant to provide units of functionality. They're ideally small and independent of any other class. You can add new functionality to your class by including different mixins.

You cannot inherit from a mixin however, meaning that they cannot appear after the ``extends`` keyword, only after ``implements``. This ensures that the ambiguous diamond pattern described in the introduction to this tutorial does not happen.

You're now going to create a mixin called ``Example.Colored`` providing coloring facilities to your classes. Any class including this mixin will have a ``color`` property added to it complete with setter and getter. Your class won't be modified since the mixin provides all the implementation.

You will only be adding the mixin to some of the classes, to show how you can mix and match classes and mixins to suit your needs.

Start by creating yet another Eo file: ``example_colored.eo``:

``` mixin Example.Colored {

 methods {
    @property color {
       get {
       }
       set {
       }
       values {
          red: int;
          green: int;
          blue: int;
       }
    }
 }

} ```

As you can see it looks like a regular class named ``Example.Colored`` providing a single property called ``color`` composed of ``red``, ``green`` and ``blue`` integer values. There's nothing remarkable besides the fact that the keyword ``mixin`` is used instead of ``class``.

Turn into C code using the usual ``eolian_gen`` command:

```bash eolian_gen -gchi example_colored.eo ```

Edit the includes file ``eo_multiinherit.h`` as before and add the newly generated ``example_colored.eo.h`` after the other includes:

```c #include “example_colored.eo.h” ```

## Step Nine: Implementing the Mixin ##

The implementation of this mixin is simple, just a standard setter and getter for the property. Open ``example_colored.c`` then:

* Replace the ``#include “example_colored.eo.h`` with ``#include “eo_multiinherit.h“``

* Add ``int red, green, blue;`` inside the structure ``Example_Colored_Data``.

* Implement the setter as: ``pd->red = red; pd->green = green; pd->blue = blue; ``

* Implement the getter as: ``*red = pd->red; *green = pd->green; *blue = pd->blue;``. Add checks for ``NULL`` pointers for added security.

The full ``example_colored.c`` file should look like this:

```c #define EFL_BETA_API_SUPPORT #include <Eo.h> #include “eo_multiinherit.h”

typedef struct {

 int red, green, blue;

} Example_Colored_Data;

EOLIAN static void _example_colored_color_set(Eo *obj EINA_UNUSED, Example_Colored_Data *pd,

                         int red, int green, int blue)

{

 pd->red = red;
 pd->green = green;
 pd->blue = blue;

}

EOLIAN static void _example_colored_color_get(const Eo *obj EINA_UNUSED, Example_Colored_Data *pd,

                         int *red, int *green, int *blue)

{

 if (red)
   *red = pd->red;
 if (green)
   *green = pd->green;
 if (blue)
   *blue = pd->blue;

}

#include “example_colored.eo.c” ```

## Step Ten: Including the Mixin ##

Modify ``example_rectangle.eo`` to include the ``Example.Colored`` Mixin. There's nothing to do beyond adding the Mixin name in the inheritance list:

``` class Example.Rectangle extends Efl.Object implements Example.Shape, Example.Colored {

  [...]

} ``` The Mixin provides a new property to the class, and takes care of its implementation. ``Example.Rectangle`` (and its derived class ``Example.Square``) can start using this new property without further work. You can now generate the C files as usual:

```bash eolian_gen -gchi example_circle.eo -I . ```

## Step 11: Using the Mixin ##

Modify ``eo_multiinherit_main.c`` to make use of this new functionality. There's little to change.

Add a new configuration call to ``example_colored_color_set()`` in the creation of the rectangle:

```c

 rectangle = efl_new(EXAMPLE_RECTANGLE_CLASS,
                     efl_name_set(efl_added, "Rectangle"),
                     example_rectangle_width_set(efl_added, 5),
                     example_rectangle_height_set(efl_added, 10),
                     example_colored_color_set(efl_added, 255, 0, 0));

```

Do the same for for the creation of the square:

```c

 square = efl_new(EXAMPLE_SQUARE_CLASS,
                  efl_name_set(efl_added, "Square"),
                  example_rectangle_width_set(efl_added, 7),
                  example_colored_color_set(efl_added, 64, 64, 64));

```

There's no need to modify the circle creation since you didn't include the mixin in ``Example.Circle``.

Finish off by printing some additional information in ``_shape_print()`` in case the requested shape includes the ``Example.Colored`` mixin. Right after the previous ``printf()`` call:

```c

 if (efl_isa(shape, EXAMPLE_COLORED_MIXIN))
   {
      int red, green, blue;
      example_colored_color_get(shape, &red, &green, &blue);
      printf("  Colored %d, %d, %d\n", red, green, blue);
   }

```

``efl_isa()`` checks if the ``Efl.Object`` passed in the first parameter contains the class specified in the second parameter in its inheritance tree. In other words it returns ``true`` if any of the ancestors of the object are of the given class or implement the given interface or include the given mixin. If that is the case, you will print the color information using the ``color`` property.

If you do not perform the ``efl_isa()`` check you will be assuming that all shapes contain the ``color`` property, which means the program will display an error at runtime.

Build your program, including the additional ``example_colored.c`` file:

```bash gcc eo_multiinherit_main.c example_rectangle.c example_square.c example_shape.c example_circle.c example_colored.c `pkg-config –cflags –libs elementary` ```

Upon running, you should see this in your terminal:

``` Shape named Circle has area 78 Shape named Rectangle has area 50

Colored 255, 0, 0

Shape named Square has area 49

Colored 64, 64, 64

```

As you can see, only the rectangle and the square contain color information since only the rectangle includes the ``Example.Colored`` mixin (and the square inherited it).

## Summary ##

In this tutorial you've learned:

* multiple inheritance is possible with Eolian, with some restrictions.

* Only one class can be inherited from, but multiple interfaces can be implemented and multiple mixins can be included.

* How to create interfaces and implement them in other classes.

* How to create mixins and include them in other classes.

* How to find if an object has a given class in its inheritance tree using ``efl_isa()``.

This tutorial concludes the series about Eolian.

## Further Reading ##

[Class Inheritance with Eolian](eo-inherit.md) : Introduces class inheritance with Eolian.