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!