Software Carpentry is gnashing through object-oriented programming.
It seems like the de facto way of teaching object-oriented programming involves diving into inheritance and polymorphism. These tend to take up a large proportion of the time because inheritance and polymorphism are hard.
I think the amount of time spent on these concepts is disproportionate to the amount they are used and encourages the overuse of these tools.
Composition, delegation and other relationships can all be modeled using references to other objects. Inheritance, however, relies on modeling a domain using only specialization relationships.
I think very few real domains actually are modeled really nicely using inheritance hierarchies. I can only think of a few examples: Actors in simulations such as games, data structure libraries, and graphical user interfaces.
Where there is no way to model a domain using specialization, you’re actually lucky. In some cases, there is more than one way to model a domain using specialization. For example, you might be tempted to specialize objects that have physical properties. Some of them have behaviours related to mass, some related to energetic activity. Do you impose a partial ordering on the dimensions? Which partial ordering? Do you teach mixins? Multiple inheritance? Or do you try to teach why you should discard inheritance in this case?
Thankfully for the real world, the kind of domain modeled by inheritance tends to be the kind of domain where a few experts write a library that everyone then uses. This further reduces the argument for teaching inheritance.
Nearly all other relationship types degenerate into composition, delegation and reference.
Of the holy triumvirate of object-oriented principles (Inheritance, Polymorphism and Encapsulation) I think Encapsulation deserves the centre stage and the bulk of the attention, but it doesn’t get it. I like to ask “What information does this class protect from others?” It’s a much more productive question than devising inheritance relationships, which can be viewed as the task of sorting out a partial ordering of dimensions of classification of objects i.e. complicated.
Inheritance should be viewed simply as just one method of code reuse, and a particularly hard-to-use one at that. As such it is appropriate for programmers learning about refactoring and advanced code quality practices (i.e. advanced programmers only). At this time programmers will have a much stronger foundation for understanding this concept. Proper design of inheritance hierarchies requires thinking cleanly about TWO external interfaces for a class: The typical object and the interface to subclasses.
To make matters worse, we’ve only been discussing traditional inheritance. Prototype inheritance is another paradigm entirely. Many smart people think prototype inheritance is a better system overall, but the world is stuck with these 1970s concepts.
So to sum up this rant:
- Inheritance is hard to use right in the real world.
- Compared to other object relationship types, inheritance isn’t used that much in the real world.
- Inheritance is just one of many ways of reusing code.
- Inheritance is taught too early to novice programmers.
- Inheritance consumes too much of the object-oriented education curriculum.
In my view, instead of the status quo we should:
- Teach objects only in the context of information-hiding. Treat classes as simple, standalone templates for objects.
- Teach delegation as the primary method of code reuse.
- Omit discussions of inheritance until as late as possible.