deft flux

A portal into the creative workings of David Meyer

A good design for multiple implementation inheritance

I had an interesting idea.  See, there's a good reason .NET does not allow multiple class inheritance, although multiple interface inheritance is allowed.  But there are some cases when it would be nice to be able to inherit the behavior of a class while still inheriting from another class.  Consider a simple example.

Say we have a class named Dog and a class named Cat.  As logic would tell us, there is no way something could be both a Dog and a Cat; hence, we cannot inherit both Dog and Cat.  An interface, however, has a different purpose than a class.  Instead of representing a type of object and including its implementation, an interface is intended to describe one or more capabilities of an object.  For instance, we might have an interface called IBarkable, which the Dog class would implement, describing its ability to bark.  Similarly, an IMeowable interface.  Now while there is nothing that is both a dog and a cat, there easily could be an object that has some of the capabilities of both.  For instance, a human can both imitate a dog's bark and a cat's meow.  So it makes sense that a class can implement more than one interface.

However, say we wrote the Dog and Cat classes already and now we're writing a Human class.  We've already written the code that performs the bark and the meow, how do we get that implementation into the Human class?  Now this is a very simple example and could probably be easily done a number of ways, but there are more complex situations similar to this where multiple inheritance would be helpful.  But it still does not justify allowing a class to inherit two base classes.

Here's where my idea comes in:  A new kind of type called a behavior.  Its purpose would be to define an implementation of a capability that is inheritable in a class.  Here's how a behavior would differ from a class:

  • A behavior would be implicitly abstract in that it could not be directly instantiated.
  • Polymorphism would not apply to behaviors.  Meaning that an implementing class could not be referenced as an object of a behavior.  As a result, variable types, parameter types, etc. could not be behaviors.  This would prevent the poor designs multiple inheritance would normally enable.
  • A behavior could implement interfaces and inherit other behaviors, but it cannot inherit a class.
  • A behavior could specify a constraint similar to a generic constraint where the class that implements a behavior must inherit a given base class.
  • All protected and public members of a behavior must be overridable.

Thus, to solve the above example, a Bark behavior and Meow behavior could be defined, which implement the IBarkable and IMeowable interfaces.  Dog could inherit Bark, Cat could inherit Meow, and Human could inherit both.

Another example that comes to mind are the various WinForms control classes.  You'll notice that Form inherits ContainerControl which inherits ScrollableControl which inherits Control.  But does it logically follow that every container control is also scrollable?  What if the container and scrollable capabilities were implemented as behaviors?  Then a control could inherit the container capabilities without inheriting scrollability, and Form could still inherit both.  Both behaviors would specify a constraint that the class must inherit Control so that they would have access to the members of the Control class.  (That would be one strong advantage over using a simple aggregate relationship instead.)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Development
Posted by deftflux on Thursday, October 30, 2008 8:25 PM
Permalink | Comments (4) | Post RSSRSS comment feed

Comments