Instantiate an Interface [duplicate]

2019-03-07 04:47发布

问题:

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?

回答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.