The concept of the interface in Java is undoubtedly one of the best things about the language. It almost, but not quite, makes up for not having pure multiple inheritance. I particularly like the fact that you can define zero or more method signatures as well as zero or more constants.
But why not allow abstract method bodies? If that sounds like a contradiction in terms, let me try to explain. I'm using the term
abstract in the sense of
non-concrete. Let's take an example. You define an interface called
SetOperable<T> and you define the following methods:
public abstract SetOperable<T> intersect(SetOperable<T> s);
public abstract SetOperable<T> union(SetOperable<T> s);
public abstract Collection<T> members();
public abstract SetOperable<T> clear();
public abstract SetOperable<T> add(T t);
Now, whereas you want to be able to implement the set operations on any type T, you are clearly going to have to define, in a concrete type, either the intersect or the union method. But the other method is normally derivable in terms of the first.
So, in Java, you must create an abstract class which implements the required interface and which looks something like the following:
public abstract class SetOperable_<T> implements SetOperable<T> {
@Override
public SetOperable<T> union(final SetOperable<T> s) {
final Collection<T> temp = new ArrayList<T>(members());
temp.addAll(s.members());
final SetOperable<T> intersection = intersect(s);
final SetOperable<T> result = intersection.clear();
final Collection<T> duplicates = intersection.members();
final Iterator<T> iterator = temp.iterator();
while (iterator.hasNext()) {
final T t = iterator.next();
if (duplicates.contains(t)) {
iterator.remove();
duplicates.remove(t);
}
}
for (final T t : temp)
result.add(t);
return result;
}
}
Concrete classes will extend this abstract class, defining the details of
intersect,
members,
clear,
add, etc. But it would be so much nicer to be able to define this
union method
in the interface itself and not have to bother with an abstract class, assuming of course that you can define the method in terms of the interface (or its super-interfaces). Scala allows you to do just that, at least in its own way, but not Java.
I admit that it's not the end of the world, but it can be awkward if you have a concrete class that should extend some other type as well as extending the above abstract class. You can't have it extend both. In the given example, you might want your concrete class to extend
AbstractSet, for example.
OK, back to work!