tags:

views:

117

answers:

3

I use interfaces/abstract base classes for most of my types and don't often inherit from concrete classes but I've recently run into a situation where either inheritance or composition is desired. I've been aware of the adage "program to an interface, not an implementation" but recently decided to dig deeper.

I've seen arguments against inheritance, and I've seen counter arguments but I'm curious as to what other maintainers of large code bases actually do in real life. Is the fear overblown? Do you inherit from concrete classes, or are the inheritance skeptics correct? I'm particularly interested in hearing from those people that work in C++.

+2  A: 

You can privately derive from concrete classes. Private inheritance doesn't require Liskov substitutability; it's essentially just a convenient way to "mix in" a class's functionality.

Public inheritance, on the other hand, does require Liskov substitutability. So, usually, publicly inheriting from concrete classes is a bad thing, unless such a class is designed to be used as a base class (many are not).

Chris Jester-Young
Many which aren't designed so can be redesigned/refined a little to support it, as well.
Potatoswatter
+6  A: 

Not a C++ guy (have professional experience with big enterprise systems in c#, java, and ruby), but here is my 2 cents anyways

This isn't a black and white thing.

The problem with inheritance is that it introduces tight coupling. Worse, that coupling is usually around encapsulated state. Changes in super classes can have rippling effects down inheritance hierarchies, creating subtle and hard to predict bugs.

Interface segregation totally sidesteps those issues, because it doesn't break encapsulation the same way.

The good thing about inheritance is that sometimes you have an object model that really is the same thing, just with a very small change or addition. As long as that change is very clear, not wide reaching in scope, and isn't an additional constraint (see the circle-ellipse problem), the code reuse will trump the tight coupling.

I stick to composition over inheritance as a rule of thumb, not a law.

Matt Briggs
Oh hey. Just a heads-up, your avatar is identical to Mike Stone's. I actually asked him about it, and he said to me that he actually made the avatar himself, by stepping frame-by-frame through the particular episode and actually manually editing out the background. I don't think he appreciated people ripping his avatar, either. :-(
Chris Jester-Young
@Chris: Oh crap. I actually ripped it off of a buddies MSN avatar (who is not mike stone, and ironically had no problem with me using it), figured he just got it from a google search. I'll change it asap.
Matt Briggs
@Chris: got a fry flying his scootie-puff junior off of some random avatar site, should change whenever SO expires their caches. What are the odds that something you get over msn turns out to be the lovingly crafted product of a real active user of a forum you happen to be active on?
Matt Briggs
Cool, thanks! Yeah, things do bounce around the Internet for sure, so, these things happen. \*nods\* But yes, it's a small world, right? ;-)
Chris Jester-Young
A: 

Good design stipulates that concrete classes should do a single, relatively small thing well and efficiently. Especially in C++, concrete classes emphasize their similarity to concrete types like int and char, often by operator overloading and by having only non-virtual functions. As concrete classes are not intended to display polymorphic behavior, they should not be inherited. Also see section 25.2 of The C++ Programming Language for more information on the proper use of concrete types in that language.

Vijay Mathew