Suppose for a program that I needed a List of some kind. Any kind of List will do, so I create one.
List<Integer> example = new LinkedList<Integer>();
I've heard that it's good practice, when instantiating your objects, to define them as interfaces, if you are doing something that requires the use of that interface, but not necessarily that specific concrete class. For example, I could have made that "example" list an ArrayList instead.
However, defining my LinkedList to be a List interface in this way limits me. I can't use any of the LinkedList-specific methods, for example. I can only use methods that are in the List interface itself. The only way I've found to use my LinkedList-specific methods are to cast example to a LinkedList, like so:
((LinkedList)example).addLast(1);
...which seems to defeat the purpose, since by casting "example" to be a LinkedList, I may as well have created it and defined it to be a LinkedList in the first place, instead of a List.
So why is it good practice to create concrete classes and define them via interface? Is there something that I am missing?