Object-orientation
Object-orientation is about classes and objects. A class is an abstract data type:
- data type: because it defines a new type to work with by providing data and operations on this data, but also
- abstract: because it encapsulates this data and hides implementation details behind an hopefully nice and clean interface.
An object then is an instance of a class. Of course, each class can have as many objects as needed by the application.
OO and polymorphism go hand in hand. Polymorphism means:
- one interface, which has
- multiple (~poly) implementations (~forms ~morphs).
A base (top-level) class defines the interface while sub-classes implement the interface. Sub-classes can also inherit properties of their base class(es). This is also called inheritance.
It is interesting to mention that a class without inheritance is a black box. No one can ‘look’ inside the class. This is not true when a class is sub-classed, and therefor, such a class is called a white box. Black box has preference over white box.
The main benefits of OO are:
- code re-use (code of the base class can be re-used by sub-classes — implementation inheritance), and
- more generic code: it allows developers to write ‘against’ an interface i.e. without having to think about specific interface-implementations. Sub-classes, in this context better called ‘subtypes’, implement the interface of a base class or ‘supertype’ — interface inheritance.
Class re-use is of course possible but tends to be more difficult than expected. The reason is because a class has good ‘outside-in’ but bad ‘inside-out’ coupling (a class uses other classes which again use other classes etc.). Low-coupling and as a consequence high cohesion (being good in one thing) leads to class re-use. (You might want to read about component-based software engineering in which loosely coupled components are composed into a system.)
Object-orientation in C
In C – and this in contrast with many other languages such as C++, Java, Python, Ruby etc. – there is no explicit support for object-orientation. But do not worry, there are (not very difficult) solutions.
A simple class without inheritance/polymorphism support
If you want to have an abstract data type with operations then here is a simple way to do this:
#ifndef MY_CLASS_H #define MY_CLASS_H struct my_class; /* 'constuctors' and 'destructor' */ struct my_class * my_class_alloc1(void); struct my_class * my_class_alloc2(int x, int y); void my_class_free(struct my_class * c); /* operations */ void my_class_operation1(struct my_class * c); int my_class_operation2(struct my_class * c); #endif
The clue is to use a C forward declaration struct my_class;. The user of this class (or C module) is unable to see the struct definition (which resides in the my_class.c file) and only works with an opaque pointer. All ‘private’ functions belong in another (non-exported) header file.
A consequence of not being able to see the struct definition is that users can only rely on alloc and de-alloc functions to create and destroy objects.
Addendum: better abstraction in C?
In C++ a class definition is always visible – even private and protected functions and members. If we forget about technical reasons (friends, inheritance etc.) then – from the point of view of a user – why do we see these private/protected functions and members?
Part 2
In Part 2 we elaborate on this subject and show you some real inheritance and polymorphism!
FYI,
Object-oriented design patterns in the kernel, part 1 : http://lwn.net/Articles/444910/
Object-oriented design patterns in the kernel, part 2 ; http://lwn.net/Articles/446317/