Programming question: Implementation Inheritance

I can think of all kinds of good reasons not to use implementation inheritance, but are there any cases where you should or have to use it?

Thanks for your help,
Rob

Check out the template pattern.

A lot of the reasons you hear around the net for not doing implementation inheritance are post hoc arguments made by people defending their favorite language – the majority of which don’t support it.

The real world is full of cases where things are derived from two independent classes: Ford is-a American Automaker and Ford is-a Class A Internet Address owner.

If you’re modelling such a situation but don’t get interface inheritance, you have to decide which of these two things is “more important” (in the sense that you’re willing to inherit rather than implement) – a choice that’s going to be hard to make in many cases, and even if it’s obvious for your implementation, it going to be obviously wrong for someone else’s (consider the case of the ProduceCars() method vs. the GetSubnet() method).

In general, I’d argue that if you’re really modelling multiple is-a relationships, and your language supports it, you’re better off inheriting most of the time, because that’s what is-a usually means.

Look at some code out there that follows the “no implementation inheritance” rule, and you’ll see an awful lot of code copied from one one implementation of the interface to the next. That’s an awful lot worse for maintainability than inheriting the implementation would have been.

I can’t think of cases where you would have to use it. Presumably, any implementation that would be shared could just be copied-and-pasted in both implementations. You might have a hierarchy with singleton (static) member that you want shared between interfaces. Deriving both implementations including the static member makes it easy, but you could solve that other ways too.

As for when you would want-to is a tradeoff that depends with the situation. If the two classes are very, very similar and share a large amount of code, then that is a good candidate for implementation inheritance. When I do this, I still put an interface class at the top of the hierarchy so that new flavors are not obligated to use the shared implementation.

For example:



interface
    base_implemenation
        concrete_class_A
        concrete_class_B

More specifically:


Phone (interface only)
    NetworkPhone (abstract base class, can't be instantiated)
         SIPPhone
         H323Phone
         IAXPhone
    GSMPhone (concrete class that implements the entire interface)

Without implementation inheritance you can always work around duplicating code by pulling it out into stand-alone classes and sharing them. It really depends a lot on your current task and your best-guess at the future tasks as well as other things like team size, code size, team experience, deadlines, etc. This is why concious refactoring is so cool, because you can switch from one to the other if you initially made the wrong trade-off.