Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

Why extends is evil

Improve your code by replacing concrete base classes with interfaces

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

The extends keyword is evil; maybe not at the Charles Manson level, but bad enough that it should be shunned whenever possible. The Gang of Four Design Patterns book discusses at length replacing implementation inheritance (extends) with interface inheritance (implements).

Good designers write most of their code in terms of interfaces, not concrete base classes. This article describes why designers have such odd habits, and also introduces a few interface-based programming basics.

Interfaces versus classes

I once attended a Java user group meeting where James Gosling (Java's inventor) was the featured speaker. During the memorable Q&A session, someone asked him: "If you could do Java over again, what would you change?" "I'd leave out classes," he replied. After the laughter died down, he explained that the real problem wasn't classes per se, but rather implementation inheritance (the extends relationship). Interface inheritance (the implements relationship) is preferable. You should avoid implementation inheritance whenever possible.

Losing flexibility

Why should you avoid implementation inheritance? The first problem is that explicit use of concrete class names locks you into specific implementations, making down-the-line changes unnecessarily difficult.

At the core of the contemporary Agile development methodologies is the concept of parallel design and development. You start programming before you fully specify the program. This technique flies in the face of traditional wisdom—that a design should be complete before programming starts—but many successful projects have proven that you can develop high-quality code more rapidly (and cost effectively) this way than with the traditional pipelined approach. At the core of parallel development, however, is the notion of flexibility. You have to write your code in such a way that you can incorporate newly discovered requirements into the existing code as painlessly as possible.

Rather than implement features you might need, you implement only the features you definitely need, but in a way that accommodates change. If you don't have this flexibility, parallel development simply isn't possible.

Programming to interfaces is at the core of flexible structure. To see why, let's look at what happens when you don't use them. Consider the following code:

f()
{   LinkedList list = new LinkedList();
    //...
    g( list );
}
g( LinkedList list )
{
    list.add( ... );
    g2( list )
}


Now suppose a new requirement for fast lookup has emerged, so the LinkedList isn't working out. You need to replace it with a HashSet. In the existing code, that change is not localized since you must modify not only f() but also g() (which takes a LinkedList argument), and anything g() passes the list to.

Rewriting the code like this:

f()
{   Collection list = new LinkedList();
    //...
    g( list );
}
g( Collection list )
{
    list.add( ... );
    g2( list )
}


makes it possible to change the linked list to a hash table simply by replacing the new LinkedList() with a new HashSet(). That's it. No other changes are necessary.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (17)
Login
Forgot your account info?

The ForestBy Anonymous on January 7, 2010, 12:45 amAlright, I agree and disagree with a lot that is postulated in this article and in the comments. However, since we are talking OO, lets get down to basics. Object...

Reply | Read entire comment

This is why ages ago theyBy Anonymous on November 4, 2009, 5:33 pmThis is why ages ago they invented unit testing. You say this is agile development? In real life you scetch a Base class and then build a whole framework over it...

Reply | Read entire comment

You can't avoid assumptions about implementationBy Anonymous on October 30, 2009, 4:49 amSomebody has the bright idea to add a duplicate method to the stack class, which duplicates the element on top. It doesn't muck about with pop, push, push; it takes...

Reply | Read entire comment

Assumptions about implementation cause problemsBy Anonymous on October 1, 2009, 6:02 pmMonitored_Stack assumes details of the implementation of Stack. When those details change, Monitored_Stack breaks. A better design would have been to override...

Reply | Read entire comment

Java Collections FrameworkBy Anonymous on September 11, 2009, 12:09 pmIt's less of a problem when the class you are extending is in the same package.

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources