Implementation Vs Interface Inheritance. Is Implementation Inheritance Bad?

Well that has been a big discussion lately, whether or not to use concrete inheritance. Jim Gosling when asked if he would do anything different if he had a chance to do it all again, and he mentioned he would like to get rid of class inheritance. Is it cause inheritance is evil or something, No. The reason its misused and abused and is one of the biggest reasons behind design failures, and application architecture havoc. Why????

Cause people use inheritance just for the sake of re-usability. While the relationship doesn’t actually exist. There are certain preconditions before a class could be inherited. See “Liskov’s Substitution Principle” for an explanation on this.

Interface deals more with a contract and can handle peripheral abilities of a class therefore interface inheritance is much safer. That’s why they say “PROGRAM TO INTERFACES”.

Well one can disagree with Gosling as much as one likes, but if given a choice I would rather be in Gosling’s camp than otherwise. Apart from the fact that the stature he enjoys in the Java community, there are the following reasons that would strengthen his point.

1. Inheritance is a clumsy and overly restrictive way to assemble objects. It binds the composition of objects extremely early which limits flexibility and it’s usually difficult to change the behavior of existing types.

2. The difference between is-a and has-a relationships is well known and a fundamental part of OOAD, but what is less well known is that almost every is-a relationship would be better off re-articulated as a has-a relationship. So aggregation/composition could actually replace most of the reusability based inheritance.

3. It violates OCP (Open Closed Principle) for the base class and the derived class. Neither class is closed for changes from either class.

4. It violates encapsulation principles for the base class, since the derived class depends and must know the implementation details of the base class.

Now coming to the face value of Gosling, well its not Gosling alone, Joshua Bloch in his book effective Java writes:-
“Inheritance is a powerful way to achieve code reuse, but it is not always the best tool for the job. Used inappropriately, it leads to fragile software.”

Further down he gives the following reasons for preferring interfaces (for explanations refer to the book):-
1. Existing classes can be easily retrofitted to implement a new interface.
2. Interfaces are ideal for defining mixins.
3. Interfaces allow the construction of nonhierarchical type frameworks.
4. Interfaces enable safe, powerful functionality enhancements.

Now who else supports this?
Rod Johnson in his book “Expert One on One J2EE Design and Development” states:-
“Concrete inheritance is enthusiastically embraced by most developers new to OO, but has many disadvantages. Class hierarchies are rigid. It’s impossible to change part of a class’s implementation; by contrast, if that part is encapsulated in an interface (using delegation and the Strategy design pattern, which we’ll discussed below), this problem can be avoided.”

About Template pattern he says:-
“Using abstract classes in place of interfaces. Abstract classes are very useful when used correctly. The Template Method design pattern (discussed below) is usually implemented with an abstract class. However, an abstract class is not an alternative to an interface. It is usually a convenient step in the implementation of an interface. Don’t use an abstract class to define a type. This is a recipe for running into problems with Java’s lack of multiple concrete inheritance. Unfortunately, the core Java libraries are poor examples in this respect, often using abstract classes where interfaces would be preferable.”

And finally Martin Fowler in his book UML Distilled states:-
“Although inheritance is a powerful mechanism, it brings in a lot of baggage
that isn’t always needed to achieve substitutability . A good example of this was in
the early days of Java, when many people didn’t like the implementation of the
built-in Vector dass and wanted to replace it with something lighter . However,
the only way they could produce a dass that was substitutable for Vector was to
subclass it, and that meant inheriting a lot of unwanted data and behavior .”

And the list goes on and on and on, what needs to be ensured is that whenever implementation or concrete inheritance is used it should be ensured that one is not violating LISP. If one is not sure about that in such a case as per the gurus there is only one word “AVOID”.

About Khurram

“If I had only one hour to save the world, I would spend fifty-five minutes defining the problem, and only five minutes finding the solution.” ― Albert Einstein
This entry was posted in Java and tagged . Bookmark the permalink.

Leave a comment