I have heard several times that when instantiating objects you should do:
"Interface" name = new "Class"();
For example for the class linkedlist that implements List
:
List<String> name = new LinkedList<String>();
LinkedList
implements many interfaces, including queue, deque, etc. What is the difference between the above code and
LinkedList<String> name = new LinkedList<String>();
or
Queue<String> name = new LinkedList<String>();
Why must the type be specified twice as well; it seems redundant but oracledocs don't seem to mention it.
There are a few key differences.
The difference between using the
List
interface and using aLinkedList
object is that I'm defining my interaction with the implementing object to adhere to theList
interface. Ultimately, I don't care what the implementation is*, so long as it behaves like aList
of some kind.If I use the concrete
LinkedList
object, then I not only have to care what the type is, but I can use more things than I probably should - since it implements theQueue
interface too, I can do queue-like operations on it, which may or may not be appropriate.Ultimately, your code should be SOLID; here, we adhere to the dependency inversion principle, which allows us to depend on the interface as opposed to the concrete implementation. It allows us to subsitute the
LinkedList
for anArrayList
should we want to.*: Of course you should care what the underlying implementation is, for performance reasons. But, you may not care yet.
LinkedList<String> name = new LinkedList<String>();
is redundant in Java 7. It can be rewritten toLinkedList<String> name = new LinkedList<>();
.The reason you want to write something similar to:
is to provide you with the freedom of changing your data collection later, if you change your mind. Your code is much more flexible this way. What you should note about this, is that the methods you are able to use are limited to the left-hand side type (
List
in this case). This means that you may not get all the functionality you want, if you use a type that is higher in the hierarchy (Object
being the extreme example).Will expose the methods that are defined in
LinkedList
and its superclasses.Will expose the methods that are defined in
Queue
and the interfaces it extends.You should define the object as a class/interface that holds everything (methods, variables, etc) that you need, while also making it as abstract as possible.
This hides implementation details and allows for easier switching between implementation, for example.
Note that you don't have to specify the type in the initialization due to the diamond operator.
If you code to interfaces you can easily switch implementations easily. If an ArrayList suits your needs better than a LinkedList then you can change one line only. If you need a particular method that is in the LinkedList class (or any other of the sub types) then it is perfectly valid to have
As for the redundancy if you are referring to the generic type declaration then I would recommend you look at the Guava libraries. These have some nice static import methods to remove this. For example for an ArrayList it would be
instead of
There is a similar method for LinkedList too.
In Java 7 there is also the diamond operators but this is still a bit more verbose than the static import from Guava.
This isn't as simple as it looks. If you use:
if you ever wanted to switch from linked lists to arraylists it would be less maintenance.
About the redundancy,
List name = new LinkedList()
declaresname
of typeList
and invokes theLinkedList
constructor. You could have as follows:This helper method "just happens" to return a list, so there is no redundancy.
With Java 7 the apparently-redundant generic args can be skipped:
as opposed to
Firstly, an Interface is a abstract type that is used to specify what a classes must implement. Any class the implements an interface must satisfy its contract by implementing its method and is of that type.Therefore, by implementing the List interface LinkList is a type of list.
By coding to the interface and not to the concrete class your code becomes more loosely coupled. This means that your code is not bound to the LinkList but rather the List interface and can be changed to anything that implements the list interface at anytime. Therefore, if for some reason the LinkList no longer meets you requirements and you need, lets say a ArrayList instead since it also implements the List interface you can just change to :
And all your other programming logic would remain the same,since both classes have the same methods because they implement the same interface.