This question already has an answer here:
-
What does it mean to “program to an interface”?
31 answers
-
Initializing an Interface?
2 answers
Extending the question asked in Initializing an Interface? , we do instantiate an Interface while initialize it with implemented class.
My question is why in the first place, we are instantiate it with the Interface? Why can't I directly instantiate it with implemented class?
For eg. :
Doc mydoc = new SimpleDoc();
Where Doc is interface and SimpleDoc is implementing it.
What is the problem with
SimpleDoc mydoc = new SimpleDoc();
Where this will fail?
It's generally good practice to depend on abstract types (interfaces or abstract classes) within a system.
In your example, you could indeed write:
SimpleDoc mydoc = new SimpleDoc()
However the problem is that code that uses mydoc
will depend on the concrete type SimpleDoc
. This isn't necessarily a problem in itself, however, suppose you create a new implementation of Doc
, say ComplexDoc
.
You'd change your declaration to:
ComplexDoc mydoc = new ComplexDoc();
Now all the places methods that you pass mydoc
to would also have to change.
However had you used Doc
in the first place you'd have a single change to make with:
Doc mydoc = ComplexDoc();
This is particularly useful when you are working with the Collections API, where it's common to switch one implementation of another or when using Mocking in test case.
If you uses a interface instead of implementation class in clients code, you are able to change implementation without changing clients code.
If you write:
SimpleDoc mydoc = new SimpleDoc();
all the further code may depend on details exposed by the implementing class SimpleDoc
. But if you write:
Doc mydoc = new SimpleDoc();
the further code my only depend on aspects exposed by Doc
, which make the code even work if you decide in the future to write:
Doc mydoc = new ComplexDoc();
A good example for the differences is List
, which has at least two implementations:
ArrayList
LinkedList
If you write:
List list = new ArrayList();
you are free to replace it later with:
List list = new LinkedList();
without breaking the code relying on the variable list
(assuming you did not used casts or reflection to access implementation specific features of list
).
That is what we called as Virtual Method Invocation or Late Binding
Let us look at an example.
public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}
Now, the Deer class is considered to be polymorphic since this has multiple inheritance. Following are true for the above example:
A Deer IS-A Animal
A Deer IS-A Vegetarian
A Deer IS-A Deer
A Deer IS-A Object
When we apply the reference variable facts to a Deer object reference, the following declarations are legal:
Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d
All the reference variables d,a,v,o
refer to the same Deer
object in the heap.