I stumbled across this really old article titled ‘Why Extends Is Evil’ by Allen Holub.
A solid bunch of OO practitioners out there seem to think along the lines of what this article is stating, namely, that using ‘extends’ is bad, and you should rather implement interfaces. The problem I have with this view is that I have come across a lot of software engineers out there who follow this view, but to a degree that they seem to be suffering from a kind of ‘implementitis-syndrome’.
Exhibit A :
The above diagram comes from a project I had the misfortune of working on for a company that will remain nameless. The architecture of the system shocked me so much when I first started on the project that I had to write down the UML diagram, to figure out what the hell was going on. Everything in this diagram is an interface save for about 3 classes that I have coloured blue. There obviously was some ridiculous interface bloat going on, also everything could probably be represented in only two or three interfaces or super classes.
My point is that, had this ball of mud contained an ‘extends chain’ going straight through the middle of this diagram, while still looking pretty awful, it would have started to make a bit more sense.
Extends adds semantic structure. Rather than looking like a tumbleweed, your class diagram would look more like a tree. The classes extending each other act like the tree trunk.
Extends also adds semantic meaning. An extends relationship is a IS A relationship, and implements relationship is a IS LIKE A relationship. Interfaces should end in “-able” (Runnable, Clonable), because they are defining a characterisitic about the object. You wouldn’t have a car implement a vehicle.. that is clearly an IS A relationship.
If you were to define everything as an interface. Everything just becomes vague mush.
Holub talks about a ‘fragile base class problem’. I think you can avoid this problem by making all classes that get extended from abstract. A developer is not going to be as inclined to play around with the internals of an abstract class; the developer knows that classes extend from it. I also think that liberal use of abstract methods prevents the base class from being fragile. In essence really, I think overriding non-abstract methods is the real problem in this story.
At the end of the day you should really try and avoid inheritence, and only use it when things can’t be done with composition. But my tip would be to leave implements out of the picture until you find a proper inheritence structure using extends.