Reputation: 757
I'm learning that it is generally better to make the declared type as general as possible, but I'm not sure why. For example, in most cases, this...
List<String> myList = new ArrayList<String>();
is considered better than this:
ArrayList<String> myList = new ArrayList<String>();
One of the reasons given for this preference is quoted below( Java - declaring from Interface type instead of Class)
Yes, you are correct. You should declare as the most general type providing the methods you >use.This is the concept of polymorphism.
However, polymorphism usually increases the amount of methods available to you because you can also access the methods of your super-types. But, in the case of declaring with interface types you actually restrict the number of methods available to you because you can only access methods in the interface, and you cannot access those just belonging to the class type.
So is this really Polymorphism? and why is it considered "more general" when it seems more restrictive, if anything, to me? What am I missing?
Upvotes: 1
Views: 154
Reputation: 9848
Say you have a method like this:
public void doSomething(ArrayList<String> items) {
// do something with the list
}
How do you call this method?
ArrayList<String> list1 = new ArrayList<String>();
doSomething(list1); // good
LinkedList<String> list2 = new LinkedList<String>();
doSomething(list2); // bad
// you'd have to make a new array list and add all the items from your linked list to it
doSomething(new ArrayList<String>(list2));
Both list1 and list2 are List's but because you made your method signature requires ArrayList you cannot pass in LinkedList, or better yet List. That is why you code to an interface - it allows you to write one method that supports any implementation of List.
If you want to make it even better, use Collection instead of list, it will support Set's as well then.
As far as "increases the amount of methods available" - what method would you call on ArrayList that is not available on List? One of the benefits of interfaces is that they hide implementation complexities from you and allows you to use difference classes via a well defined interface that hides the details of the underlying implementation.
Upvotes: 2
Reputation: 70564
Wikipedia defines Polymorphism as follows:
In programming languages and type theory, polymorphism (from Greek πολύς, polys, "many, much" and μορφή, morphē, "form, shape") is the provision of a single interface to entities of different types.
Polymorphism enables writing algorithms that can work on more than one type, therefore increasing code reuse.
For instance, if we have a method
void sort(ArrayList<String> list);
that method can only be used for sorting an ArrayList<String>
. That's not very useful. But if you have
<T> void sort(ArrayList<T> list);
the method can be applied to far more types, and is therefore more useful. But it can still only sort ArrayLists. Taking the idea farther, we have
<T> void sort(List<T> list);
which can sort any kind of list, whatever its provenance or internal representation.
Generally, your methods should require as little as possible of their arguments, to be useful in as many circumstances as possible.
Upvotes: 1
Reputation: 178263
List<String> myList = new ArrayList<String>();
is generally preferred over
ArrayList<String> myList = new ArrayList<String>();
because usually you do not need methods that are specific to ArrayList
. Usually, the methods defined in List
are more than enough to satisfy typical needs. This allows you to change the implementation without changing the rest of the code, like this:
List<String> myList = new LinkedList<String>();
and nothing else changes.
Only use the specific type for the variable if you need the methods that are specific to that type. Only use ArrayList
for your variable if you really do need ArrayList
-specific methods.
Upvotes: 2