2

We use interface references to Collections. Is it only for the good coding practice or have some logic behind it? Can anyone explain?

For example:

We use

Map<String, Integer> map = new HashMap<String,Integer>();

Instead of

HashMap<String, Integer> map = new HashMap<String,Integer>();
Shreyos Adikari
  • 12,348
  • 19
  • 73
  • 82
  • 1
    Related - http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface – Premraj Sep 21 '12 at 18:18

6 Answers6

3

Having interface will allow you to change the implementation in future transparently (Without many changes on client side).

For example:

Map<String, Integer> map = new LinkedHashMap<String,Integer>();

Even though you change implementation to LinkedHashMap, client don't need to make any changes on their end.

If you use

HashMap<String, Integer> map = new HashMap<String,Integer>();

Client is tightly coupled with implementation. If you change implementation, then you need to change client also.

One draw back would be, If you would like to use any implementation specific methods, you need to cast to the corresponding type and use it.

kosa
  • 65,990
  • 13
  • 130
  • 167
3

If you use HashMap your implementation becomes specific to HashMap but if you use Map you can change it to any Map Implementation in future.

You can read Item 52: Refer to objects by their interfaces From Effective Java.

Amit Deshpande
  • 19,001
  • 4
  • 46
  • 72
2

The idea is that you code to the contract of a component, not to the implementation. There are many implementations of java.util.Map, and can be interchanged seamlessly should the need arise, provided your code depends solely on the interface.

Loose coupling in general is good practice.

Peter Bratton
  • 6,302
  • 6
  • 39
  • 61
1

Code Maintenance is one advantage, if someone wants to use some other concrete Map, you need to change only one line versus dozens. It may not seem like that in your code snippet example, it's only when the use of object references become prevalent in parameters and return types that the problems arise. I suppose it is just better to start "thinking in interfaces" rather than objects from the beginning to avoid the tendency to write code that brings these problems about. Quoting Allen Hollub here

If you write your client code such that it is only concerned with the capabilities guaranteed by an interface rather than the actual implementation by a particular class, you will have more freedom to change implementations in the future.

Piyush Mattoo
  • 15,454
  • 6
  • 47
  • 56
1

With something as follows -

class MapTest {
    Map<String, Integer> map;

    public MapTest(Map<String, Integer> map) {
        this.map = map;
    }

    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }

    //do stuffs with map
}

you can pass in different implementations of Map. But if map was of type HashMap then it would alwasy have to be a HashMap (or it's subclass if you subclass it).

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
0

First approach is much more flexible then second:

Map<String, Integer> map = new HashMap<String,Integer>();

This way, you have to change only one line if you decide to use a TreeMap instead.

Also, methods that operate on sets should specify parameters of type Map:

public static void print(Map<String, Integer> s)

Then the method can be used for all map implementations.

In theory, we should make the same recommendation for linked lists, namely to save LinkedList references in variables of type List.

catch23
  • 17,519
  • 42
  • 144
  • 217