1

This has been bugging me for a while and have yet to find an acceptable answer. Assuming a class which is either a subclass or implements an interface why would I use the Parent class or Interface as the Type i.e.

List list = new ArrayList();
Vehicle car = new car();

In terms of the ArrayList this now only gives me access to the List methods. If I have a method that takes a List as a parameter then I can pass either a List or an ArrayList to it as the ArrayList IS A List. Obviously within the method I can only use the List methods but I can't see a reason to declare it's type as List. As far as I can see it just restricts me to the methods I'm allow to use elsewhere in the code.

A scenario where List list = new ArrayList() is better than ArrayList list = new ArrayList() would be much appreciated.

andyfinch
  • 1,312
  • 2
  • 19
  • 34
  • Duplicate? http://stackoverflow.com/questions/3768869/use-interface-or-type-for-variable-definition-in-java – Rich Feb 09 '11 at 10:26

6 Answers6

2

You write a program that passes lists around several classes and methods. You now want to use it in a multi threading environment. If you were sensible and declared everything as List, you can now make a single change to one line of code:

List list = Colllections.synchronizedList(new ArrayList());

If you had declared the list as an ArrayList, you would instead have to re-write your entire program. The moral of the story - always program to the least restrictive interface that your code requires.

OrangeDog
  • 36,653
  • 12
  • 122
  • 207
1

Using the interface or parent type is generally recommended if you only need the functionality of the parent type. The idea is to explicitly document that you don't really care about the implementation, thus making it easier to swap out the concrete class for a different one later.

A good example are the Java collection classes:

If you always use List, Set etc. instead of e.g. ArrayList, you can later switch from ArrayList to LinkedList if you find that it gives e.g. better performance. To do that, just change the constructors (you don't even have to change them all, you can mix). The rest of the code still sees an instance of List and continues working.

If you actually used ArrayList explicitly, you'd have to change it everywhere it's used. If you don't actually need an ArrayList specifically, there's nothing to be gained from using it over the interface.

That's why it's generally recommended (e.g. in "Effective Java" (J.Bloch), Item 52: "Refer to Objects by their interfaces".) to only use interfaces if possible.

Also see this related question: Why classes tend to be defined as interface nowadays?

Community
  • 1
  • 1
sleske
  • 81,358
  • 34
  • 189
  • 227
  • You are citing the wrong item in Effective Java. You mean Item 52: "Refer to Objects by their interfaces". Item 19 deals with constants in interfaces and marker interfaces. – Sean Patrick Floyd Feb 09 '11 at 10:23
  • Accepting this as the most complete answer although the others all hit upon the same concept. Thanks for this explanation. What it effectively boils down to is code flexibility and maintenance i.e. knowing a change to a different implementation of List will still work everywhere. Thanks a lot. – andyfinch Feb 09 '11 at 10:32
  • 1
    @Michael Borgwardt: Well, even for local variables, only using interfaces makes changes easier and ensures you only use the interface methods, so the same advantages apply. It's just that a local variable is easier to change in general. – sleske Feb 09 '11 at 10:40
1

The key is exactly that the interface or base class restricts what you can do with the variable. For example, if you refactor your code later to use another implementation of that interface or base class, you won't have anything to fear -- you didn't rely on the actual type's identity.

Another thing is that it often makes reading the code easier, e.g. if your method's return type is List you might find it more readable to return a variable of type List.

Sasha Goldshtein
  • 3,499
  • 22
  • 35
1

An interface specifies a contract (what does this thing do), an implementation class specifies the implementation details (how does it do it).

According to good OOP practice, your application code should not be tied to implementation details of other classes. Using an interface keeps your application loosely coupled (read: Coupling)

Also, using an interface lets client code pass in different implementations and apply the decorator pattern using methods like Collections.synchronizedList(), Collections.unmodifiableList() etc.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
1

A scenario where List list = new ArrayList() is better than ArrayList list = new ArrayList() would be much appreciated.

One concrete example: if it's a field declaration and you have a setList(), which of course should take a List parameter to be flexible.

For local variables (and fields with no setters), there is very little concrete benefit in using the interface type. Many people will do it anyway on general principle.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • It's true that the benefit for local variables& private fields is less, but there is still some benefit, for internal refactorings. Also, a strictly private field today may grow a setter tomorrow, then using an interface will be helpful. – sleske Feb 09 '11 at 12:48
  • Also, I believe code should express *intent* (as far as possible), and if I use the interface, I express that I don't really intend to use a specific type at this point. – sleske Feb 09 '11 at 12:49
  • @sleske: That's the theory. In practice, it really, really does not matter one bit. If changing the type of a local/private variable is in any way difficult, then it's not failing to use the interface type what's wrong with your code. – Michael Borgwardt Feb 09 '11 at 13:05
  • Ok, I think we agree that it does not matter much. You can either use interfaces, if only out of habit, or use concrete types if you feel in is more readable or just like it better. – sleske Feb 09 '11 at 13:11
0

You were right. In these cases, the variables are fields or local variables, they are not public interface, they are implementation details. Implementation detail should be detailed. You should call an ArrayList an ArrayList, because you just deliberately chose it for your implementation.

People who recycle cliches: look at your post and think a little bit more. It's nonsense.

My previous answer that was downvoted to death:

Use interface or type for variable definition in java?

Community
  • 1
  • 1
irreputable
  • 44,725
  • 9
  • 65
  • 93
  • Yes, it's true that it matter less for a local field, but the same advantages still apply, just inside the method. It's just that changes inside the method are easier anyway, so it's less of a problem. Personall, I believe using interfaces is a good habit, and it's simpler to always do it like that. – sleske Feb 09 '11 at 12:46