Home

Advertisement

Mon, Jan. 5th, 2009, 10:06 am
Mulitple Inheritance and why some can't seem to get it

From my readings on it, it seems to me that most problems that programmers have with multiple inheritance stem from improper object composition and a lack of understanding of HAS-A vs. IS-A. The biggest point I hear and read in regard to multiple inheritance is the Diamond Problem. Frankly, this is way overblown. One, it's just not that common to inherit from two classes with a common base class. If you're doing so, you probably shouldn't be. I've been writing C++ code since about `93, and I've never encountered the diamond problem. Two, if you actually do need to inherit from two classes with a common base class, it's really not that hard to understand and deal with it (cf. Multiple Inheritance for C++). That's why we're programmers, right?

In the Wikipedia entry for the Diamond Problem, the example given at the beginning is a perfect example of improper object composition, attempting to implement a HAS-A relationship via inheritance (an IS-A relationship), which is not at all correct. Their example is:
For example, in the context of GUI software development, a class Button may inherit from both classes Rectangle (for appearance) and Mouse (for mouse events), and classes Rectangle and Mouse both inherit from the Object class. Now if the equals method is called for a Button object and there is no such method in the Button class but there is an over-ridden equals method in both Rectangle and Mouse, which method should be eventually called?
Wow. That's just wrong all around. Class Button shouldn't inherit from Rectangle or Mouse, because it IS neither of those things! It may HAVE them, but it IS not either. Class Button HAS-A Shape member, allowing it to hold a button shape. Class Button HAS-A input event reference member allowing it to take generalized input events from it's proper event source — but then again, no, it probably shouldn't have that. It should probably implement the Observer pattern, and register itself as an observer for input events within it's shape. It should inherit from neither of these classes. This I think highlights the problem of viewing inheritance as the only way of composing objects. The Wikipedia entry for Virtual Inheritance has the same sort of problem in it's example, where they give a base class Animal, derive a class Mammal from that, and also derive a class WingedAnimal from Animal, then compose a class Bat by inheriting from class Mammal and class WingedAnimal. You say, "but a bat IS A mammal and it IS A winged animal" to which I reply "yes, but it IS A winged animal because it HAS wings!" The proper composition is to inherit from Mammal and include an instance of class Wings as a member. And POOF! the multiple inheritance conundrum vanishes! If you're trying to inherit from classes with a common base class, examine your assumptions about how your object should be composed.

So where is multiple inheritance useful? When you need your object to be two entirely different things, maybe a waitable database record, or a singleton database connection. You inherit from the singleton class and from a database connection class and there you go, there's nothing more to do to make your database connection class a singleton. Interfaces try to give you this sort of thing, but you don't get to inherit the implementation. You have to re-implement everything yourself, throwing away the whole idea of inheritance and reuse.

Mon, Jan. 5th, 2009 08:48 pm (UTC)
[info]patrick___

Yeah, I'm glad C++ allows multiple inheritance. I do use it on occasion, although I end up doing a lot more interfaces any more.

Mon, Jan. 5th, 2009 11:50 pm (UTC)
[info]reubeneater

Makes sense to me. Unfortunately one is most likely already in a situation stuck with lousy base classes that can't be changed easily.

Tue, Jan. 6th, 2009 04:15 am (UTC)
[info]robkeeney

Tell me about it! Have you ever used MFC?

Advertisement