Interfaces are defined in a header-file. Assume there is a class called Class_A and there is a class called Class_B. Then we could define the interfaces to these classes in header files and implement those interfaces in source files.
Now we want a class Class_C, which inherits from Class_A. Then we will do this by inheriting the interface. We can include the interface header file of Class_A in the interface header file of Class_C. When implementing Class_C, then we know about the interface of Class_A and can use this interface. In this way we can make use of functionality (services) provided by Class_A without knowing how Class_A has implemented its services and its datastructures. An important concept in object orientation.
Now we want a class Class_D, which inherits from Class_C and Class_B. We can do this be including the interface header files of Class_C and Class_B in the interface header file of Class_D. When implementing the interface of Class_D, we can make use of the services of the other classes.
This is in short how we do it.
I recently read an article about another way of implementing inheritance in C. Here's some code from that article.
First they defined a class called Signal and they defined an interface for it, called SignalInterface.
Code:
typedef struct Signal Signal;
typedef struct SignalInterface SignalInterface;
struct SignalInterface
{
// The signal.
Signal *signal;
// Destructor.
void (*destroy)(SignalInterface *signal);
// Interface functions.
int (*setSample)(SignalInterface *signalInterface, int index, int newValue);
int (*getSample)(SignalInterface *signalInterface, int index);
int (*resetSample)(SignalInterface *signalInterface, int index);
int (*resetSignal)(SignalInterface *signalInterface);
};
Then they defined their own interface called MySignalInterface. This interface inherits the interface SignalInterface. In their own interface, they added one signal. For
Code:
typedef struct MySignalInterface MySignalInterface;
struct MySignalInterface
{
// Inherit from Signal interface.
SignalInterface *signalInterface;
// Destructor.
void (*destroy)(MySignalInterface *mySignalInterface);
// Add new member function.
int (*invertSignal)(SignalInterface *signalInterface);
};
Here's a shortened version of the main() program they used to test. In my opinion it is not a very elegant solution for object orientation in C, because when using the interface MySignalInterface, the programmer has to know about the interface SignalInterface, which in my opinion is not very elegant. I think it would be more elegant if the MySignalInterface provided an interface to the interface functions within SignalInterface.
Code:
#include <stdio.h>
#include "MySignalInterface.h"
int main ()
{
MySignalInterface *mySignal;
int i, j;
mySignal = createMySignal ();
printf ("MAIN: Signal created\n");
for (i = 0; i < 10; i++)
{
printf ("MAIN: Set sample %d\n", i);
mySignal->signalInterface->setSample (mySignal->signalInterface, i, i);
}
for (i = 0; i < 10; i++)
{
j = mySignal->signalInterface->getSample (mySignal->signalInterface, i);
printf ("MAIN: Retrieved sample %d value %d\n", i, j);
}
i = mySignal->invertSignal (mySignal->signalInterface);
printf ("MAIN: Result of inversion %d\n", i);
for (i = 0; i < 10; i++)
{
j = mySignal->signalInterface->getSample (mySignal->signalInterface, i);
printf ("MAIN: Retrieved sample %d value %d\n", i, j);
}
mySignal->destroy (mySignal);
return 0;
}