0

Possible Duplicate:
Why should the interface for a Java class be prefered?

I m relatively new to java and i have just started on collections framework. While on ArrayList I encountered on two ways people declare it. For example to declare an ArrayList of Strings :

List<String> l = new ArrayList<String>();

or

ArrayList<String> al = new ArrayList<String>();

Which one of these two should I use and what is the difference between them?

I know that the actual methods called are decided at runtime and hence the methods called will all be of ArrayList class only but still the first declaration restricts the methods that can be called.

The first way is, I have heard, called "coding to an interface". Any method will be invoked using the variable l and hence only methods provided by List interface can be called, whereas, in the second example we can call all the methods provided not only by List but by the Object class also (like finalize(), wait() etc). So why even in the first place people even use the first declaration??

Community
  • 1
  • 1
Surender Thakran
  • 664
  • 3
  • 7
  • 21
  • you can still access `Object` class methods with `l` instance. – Prince John Wesley Jun 12 '12 at 15:05
  • @PrinceJohnWesley: how can i since `l` is a reference of an interface and interfaces don't belong to the `Object` class's hierarchy? – Surender Thakran Jun 12 '12 at 15:11
  • every object is `Object` type. `List` is the subtype of `Object` – Prince John Wesley Jun 12 '12 at 15:13
  • but `List` is an interface and i have read that interfaces don't belong to the class hierarchy, so how can it be a subtype of `Object` if it doesn't even extends it?? – Surender Thakran Jun 12 '12 at 15:15
  • The point is that you can still refer to objects by one of the interfaces that their respective class implements. So when you say "List l", you mean "An object of some class or other that implements List". And then you can call any method of the interface List on 'l'. You can also call any public method on Object-- just because you can (Object is a special class). – Neil Coffey Jun 12 '12 at 15:17
  • No. Try `instanceof` test or assign `l` to an `Object` instance or even try calling `Object` methods from `l` – Prince John Wesley Jun 12 '12 at 15:17

2 Answers2

4

You should always use least specific interface possible. This makes it easier to substitute alternate implementations if a more appropriate one exists. For example, methods that take List don't care if the list is a linked list or an array list. You can choose whichever one is more appropriate.

sjr
  • 9,769
  • 1
  • 25
  • 36
  • so the only reason to use the first way is that we can pass it as argument to a wider range of methods? even if it restricts the methods that can be called from itself? – Surender Thakran Jun 12 '12 at 15:05
  • 3
    There are only a handful of methods on ArrayList that are not on List, and it's unlikely that you want to call them. When I say "least specific interface possible", I mean "use an interface that has all the methods you want to call and no more". – sjr Jun 12 '12 at 15:08
  • @SurenderThakran Yes, restricting methods is generally seen as a good thing. Only give access to what data and methods are necessary. This reduces complexity and, in the long run, reduces maintenance time and bugs. On a personal note, less methods pop up in the context menu too; I woudln't factor that into a design decision very heavily, but it is a nice perk :) – corsiKa Jun 12 '12 at 15:09
  • @sjr I was going to ask you for a clarification on "least specific possible", but you beat me to it. Your clarification is (IMHO) the perfect way to articulate the best practice when it comes to interfaces. – corsiKa Jun 12 '12 at 15:12
  • can you guys also shed some light on the question i have asked in comments below the question? – Surender Thakran Jun 12 '12 at 15:17
  • you can call Object methods on any instance. – sjr Jun 12 '12 at 15:18
2

I personally recommend using List<String> l = new ArrayList<String>();

The reason is you typically don't need to know you're working with an ArrayList. You just need something that operates like a list. There's a lot of behaviors on ArrayList that people don't need access to. Consider "EnsureCapacity". They don't need that - they just need the List operations. As a general rule, you want to limit the exposure of data and functionality on a "need to know" basis, and users of your list do not need to know (by default) what implementation you used.

Obviously, if they do need to know that you're using an ArrayList instead of a LinkedList, for instance, then you would want to use an ArrayList reference instead of a List reference. For most purposes though, that's not necessary.

corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • yes but using `List` also restricts the methods that can be called from it as i have mentioned in the question. So are the methods provided outside of `List` not that important that we choose to ignore them for encapsulation? – Surender Thakran Jun 12 '12 at 15:08
  • Right - see my reply on sjr's answer. – corsiKa Jun 12 '12 at 15:13