问题
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?
回答1:
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.
回答2:
If you uses a interface instead of implementation class in clients code, you are able to change implementation without changing clients code.
回答3:
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
).
回答4:
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.
来源:https://stackoverflow.com/questions/22962415/instantiate-an-interface