views:

618

answers:

10

My question is, if an interface that is implemented implicitly by extending a class that already implements it, should be explicitly implemented by the class, if the class wants to advertise the fact, that it fulfills the contract of that interface.

For instance, if you want to write a class, that fulfills the contract of the interface java.util.List. You implement this, extending the class java.util.AbstractList, that already implements the interface List. Do you explicitly declare, that you implement List?

public class MyList extends AbstractList implements List

Or do you save typing by using the implicit way?

public class MyList extends AbstractList

Which way is considered better style? What reasons do you have to prefer one way or another? In which situations you would prefer way 1 or way 2?

+12  A: 

Avoid redundancy. Use method 2.

Use @Override for overrides.

krosenvold
+6  A: 

It is not a "style" question. If you are extending AbstractList which already implements List you do not need to explicitly implement List.

It's not just a question of saving typing. As the additional "implements List" is redundant, someone might spend some time trying to figure out why it's there. You're essentially writing in a guarantee that's already part of the language.

Steve B.
What happens if someone else changes AbstractList to no longer implement List? Then MyList is broken? I don't think this is a strong argument but just playing devil's advocate.
Alex Miller
I'd +1 Alex's comment.
Uri
A: 

When you extend AbstractList, MyList is of 'type' List already, so there is no need to explicityly stat (or implement) the interface.

robert
A: 

I would say the more verbatim way. Why make others that read your code has to look up what a class implements? It makes it clear of the inherit functionality of your class. But I would try to maintain consistency across all code in the project. It will be confusing if you only do it in one place but if you do it consistently they will be aware of the redundancy.

A Side Note: There are so many classes in Java and who knows them all? Even more so, who knows which classes each class implements from? You typing for an extra couple seconds saves a fellow developer a minute or two looking classes.

ddcruver
+1  A: 

Other commenters say you should avoid redundancy, and I agree with them.

To answer the general question, the only case I can think of for stating both would be if you extended (let's say) AbstractFrotzer and implemented Frobner, AbstractFrotzer implemented Frobner, but you had reason to believe that it might not in the future. If AbstractFrotzer is truly abstract, then it might not even implement all of Frobner's methods itself. This means it's possible for someone to change the contract for AbstractFrotzer without your having to change your class, or any other code that relied on your class to be a Frobner. I would, however, consider this to be a very rare circumstance, and even if it occurred and your class only extended AbstractFrotzer, it would be sufficiently easy to give it a quick semantic check and, if necessary, add the implements clause to it at that point.

Paul Brinkley
+3  A: 

I asked this same question long ago on my blog. There is a long discussion there as well if you're interested in seeing some other people's thoughts. It's interesting to note that both strategies are taken within the JDK.

I ultimately decided that a hard rule on this didn't make sense - it's better to use best judgement as to what I wanted to communicate.

Alex Miller
A: 

As a general rule, use option 2, not option 1.

Option 1 does not provide any value addition to the developer or someone who is going to maintain the code, in the vast majority of the cases..

If someone really wants to know all the roots of a particular class, any IDE should be able to do it for you, straightforward. (Eclipse: ctrl+shift+G)

What if AbstractList decides not to implement List any longer? This is not going to happen for the vast majority of general classes. What about the other less obvious (less trustworthy) ones? Of course there can be exceptions, but very few (<1% ?)

Nivas
+1  A: 

While I generally stick with option 2, I will go on a limb and argue that option 1 is actually appropriate in more cases when it is apply.

Code usability and understandability is important. The question that we have to ask ourselves is whether or not a developer using or seeing a reference to this class would intuitively understand that the class implements that interface (and is thus essentially a subtype).

In a well written class in the typical case, the name of the class should make it obvious that it implements the interface. Adding the interface would be just a redundnacy.

However, in cases where the class name does not make it obvious what interfaces it implements, and despite the smell this is the way things are and this is the name that will stuck, then it makes sense to add the implements to indicate the interface explicitly. This is also good in case someone in the future changes the hierarchy, which is possible in unintuitive inheritances like this.

Uri
A: 

I have seen this before and it doesn't feel technically correct, as many of you had already pointed out. I would think it should be obvious, however if for some reason it were not I think it would make more sense to indicate the inheritance through a class comment, rather than explicitly implementing the interface again.

What if the base class implements multiple interfaces? Do you then explicitly implement all of those interfaces, and all the way back up the inheritance chain? Obviously not, so I think the inconsistency of this approach proves itself to be wrong. Intent can be communicated in many ways, and this is not the best approach IMHO.

A: 

If you care about a user of your class being able get a list of implemented interfaces via Class.getInterfaces() then your class should mention all the interfaces in its' implements list. Class.getInterfaces() will not return the interfaces implemented by super classes. The following program will print 1 and then 0.

import java.io.Serializable;

class Test implements Serializable {
    class Inner extends Test {
    }

    public static void main(String[] argv) throws Exception {
     System.out.println(Test.class.getInterfaces().length);
     System.out.println(Inner.class.getInterfaces().length);
    }
}
Sean McCauliff