S P A C E F O L D  
data... any distance... minimal time  

When to use interfaces

Insights from a Java n00bie #1

By Colin Nicholls
July 2000

There you are, staring at your code. You thought you were doing everything the right way, your class hierarchy made sense, and yet, it seems there is no way out. You want to write clean, generic code, but you are forced into compromise. The very inelegence of your solution offends you.

In hindsight, many things are obvious. It is easy for us to read a rule or guideline and say, "..but of course! Why would anyone not follow this rule?"

The truth is that useful rules and guidelines are almost never obvious to one that has not already been exposed to them, though they may appear so at the time.

Here's one that hit me yesterday:

If two classes need to implement identical methods but do not inherit the method signature from their common superclass, then you should probably define the common method in an interface and require each class to implement it.

Although this may seem an unnecessary overhead, it made perfect sense to me after I encountered a situation where no other solution would do: I was writing a method called loadIndividual() that had to invoke a method of a an AdnLinkAppend object:

    void loadIndividual( AdnLinkAppend oService )
        oService.addIndividual( ... ) ;

This code was so useful that I found that under some circumstances, I also wanted to pass it an instance of AdnEnhancement. Trouble is, you have to declare the data type of the passed reference. Ok, we can do this, because both AdnLinkAppend and AdnEnhancement are descended from AdnService, so we just declare the datatype of the oService parameter as AdnService and we're sweet, right?

Wrong. AdnService does not contain addIndividual in its method signature, and the code won't compile. 

I really did not want to define addIndividual() in AdnService, because there were other classes descended from AdnService that did not need an addIndividual method. (I know, there are other ways of dealing with this...).

I was stuck, and the solution only came to me when I described the problem out loud: "The problem is, that I have two classes that implement the same method, but...."

There's the key: IMPLEMENT. Instantly makes you think of interfaces. At that point, the solution makes itself perfectly clear: define an interface with the common method:

    interface IaddIndividual {
        boolean addIndividual( .. ) ;

Then, force AdnLinkAppend and AdnEnhancement to declare that they implement this interface:

    public abstract class AdnLinkAppend
        extends AdnService
        implements IaddIndividual {

Having done this, I can declare the data type of the parameter in my generic method as IaddIndividual:

    void loadIndividual( IaddIndividual oService )

        oService.addIndividual( ... ) ;

Now the code doesn't complain when I pass this method an instance of either AdnLinkAppend or AdnEnhancement!

next insight