views:

216

answers:

6

Why do many Collection classes in Java extend the Abstract class and also implement the interface (which is also implemented by the given abstract class)?

For example, class HashSet extends AbstractSet and also implements Set, but AbstractSet already implements Set.

+11  A: 

It's a way to remember that this class really implements that interface.
It won't have any bad effect and it can help to understand the code without going through the complete hierarchy of the given class.

Colin Hebert
+1 Additionally, the maintainer of AbstractSet might decide to change the hierarchy and remove Set for future releases (obviously not going to happen, but might happen for other non-core classes). In this case, compilation of HashSet would fail instead of all classes that use HashSet as Set.
sfussenegger
A: 

If you only had an abstract class you couldn't make a class of your own which inherits from another class too.

Marcus Johansson
I think the question is why the concrete implementations explicitly implement the interface again, since it's already "implemented" by the abstract base class.
Joachim Sauer
+5  A: 

From the perspective of the type system the classes wouldn't be any different if they didn't implement the interface again, since the abstract base classes already implement them.

That much is true.

The reason they do implement it anyways is (probably) mostly documentation: a HashSet is-a Set. And that is made explicit by adding implements Set to the end, although it's not strictly necessary.

Note that there difference is actually observable using reflection, but I'd be hard-pressed to produce some code that would break if HashSet didn't implement Set directly.

Joachim Sauer
+1, For example with `getInterfaces()` : http://ideone.com/BDpdr But it would be dangerous to use this method thinking that it will give all the implemented interfaces.
Colin Hebert
+1  A: 

Unlike Colin Hebert, I don't buy that people who were writing that cared about readability. (Everyone who thinks standard Java libraries were written by impeccable gods, should take look it their sources. First time I did this I was horrified by code formatting and numerous copy-pasted blocks.)

My bet is it was late, they were tired and didn't care either way.

Nikita Rybak
While the source code of many default library classes is an ugly mess, the public interface of those classes is usually a lot better than the implementation (with some exceptions of course, such as the entire `Date`/`Calendar` mess).
Joachim Sauer
@Joachim Maybe. On the other hand, this doesn't change the public interface. E.g., when you design whole library with pen and paper, you're not gonna draw additional line between _HashSet_ and _Set_ for "readability". So, it's still an implementation choice.
Nikita Rybak
A: 

I suppose there might be a different way to handle members of the set, the interface, even when supplying the default operation implementation does not serve as a one-size-fits-all. A circular Queue vs. LIFO Queue might both implement the same interface, but their specific operations will be implemented differently, right?

Jas
A: 

I also believe it is for clarity. The Java Collections framework has quite a hierarchy of interfaces that defines the different types of collection. It starts with the Collection interface then extended by three main subinterfaces Set, List and Queue. There is also SortedSet extending Set and BlockingQueue extending Queue.

Now, concrete classes implementing them is more understandable if they explicitly state which interface in the heirarchy it is implementing even though it may look redundant at times. As you mentioned, a class like HashSet implements Set but a class like TreeSet though it also extends AbstractSet implements SortedSet instead which is more specific than just Set. HashSet may look redundant but TreeSet is not because it requires to implement SortedSet. Still, both classes are concrete implementations and would be more understandable if both follow certain convention in their declaration.

There are even classes that implement more than one collection type like LinkedList which implements both List and Queue. However, there is one class at least that is a bit 'unconventional', the PriorityQueue. It extends AbstractQueue but doesn't explicitly implement Queue. Don't ask me why. :)

(reference is from Java 5 API)

Adrian M