5

Let's say I want to make a HashMap of grades.

 Map<String,Integer> grades = new HashMap<String,Integer>(); 
 grades.put("John", 87); // this work due to auto-boxing right?
 grades.put("Luke", Integer(85)); // non-autoboxed, is this redundant? 

Why is Map on the left and HashMap<K, V>( ); on the right? Isn't it pretty much a rule that you need type consistency whenever you create an object? Unless the static type of names is Map and the dynamic type is HashMap, which presumably is a subclass of Map. But why would you want to do this? Method calls are called from the perspective of an objects static type (e.g Maps), but if there are overridden methods in the dynamic type, those methods will be called. Is this why the types are different?

Thanks! Newbie question but this stuff can be confusing...

EDIT:

Thanks! So the general format is: Interface varName = new ImplementedClassConstructor(); ? And we often choose a superclass Interface because it allows easier substitution later (e.g. if I wanted to change HashMap to TreeMap?

bambo222
  • 419
  • 7
  • 15

5 Answers5

4

This is called "programming to an interface" - a rather common and very useful practice.

Map<String,Integer> is an interface. It cannot be instantiated. Variables of interface types need to be assigned objects of classes that implement these interfaces.

HashMap<String,Integer> is a class that implements Map<String,Integer>, so the assignment is valid. If you decide to change the type later, and use TreeMap<String,Integer> instead of HashMap<String,Integer>, all you need to do is change the type in the new expression. The rest of your code would remain the same.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Look into polymorphism. Basically, a HashMap is specific type of Map, and this relationship makes the assignment possible.

ApproachingDarknessFish
  • 14,133
  • 7
  • 40
  • 79
1

Having a super class (or interface) on the left hand side and a specialized version on the right hand side is good practice, because it ensures that all future calls to your object only assume the super class (or interface). Hence you can easily replace your implementation (the right hand side), e.g. by a TreeMap or s.th. else.

Christian Fries
  • 16,175
  • 10
  • 56
  • 67
1

In this snippet of code Map is an interface, and HashMap is a concrete class that implements that interface. Only concrete classes can be instantiated, but it's OK to assign one such instance to a variable (or attribute, etc.) declared as an interface. In fact, it's considered a good OO programming practice to do so, you should try to program to an interface whenever possible.

Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
0

You are correct about the autoboxing.

It's good to use Map because it's more general. Let's say in the future you decide that you want to use a different type of Map, namely not a HashMap, then by keeping a Map, all you would need to do is change HashMap to a different Map implementation.

Steve P.
  • 14,489
  • 8
  • 42
  • 72