实例化接口

时间:2014-04-09 12:22:59

标签: java object interface initialization instantiation

扩展Initializing an Interface?中提出的问题,我们确实实例化了一个接口,同时用实现的类初始化它。

我的问题是为什么首先,我们用接口实例化它?为什么我不能用实现的类直接实例化它? 例如。 :

Doc mydoc = new SimpleDoc();

Doc是接口,SimpleDoc正在实现它。 有什么问题     SimpleDoc mydoc = new SimpleDoc(); 这会失败吗?

4 个答案:

答案 0 :(得分:0)

如果在客户端代码中使用接口而不是实现类,则可以在不更改客户端代码的情况下更改实现。

答案 1 :(得分:0)

我们称之为虚拟方法调用后期绑定

让我们看一个例子。

public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

现在,Deer类被认为是多态,因为它具有多重继承。以下示例如下:

A Deer IS-A Animal

A Deer IS-A Vegetarian

A Deer IS-A Deer

A Deer IS-A Object

当我们将引用变量事实应用于Deer对象引用时,以下声明是合法的:

Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d

所有引用变量d,a,v,o都引用堆中的相同Deer对象。

答案 2 :(得分:0)

如果你写:

SimpleDoc mydoc = new SimpleDoc();

所有进一步的代码可能依赖于实现类SimpleDoc公开的细节。但如果你写:

Doc mydoc = new SimpleDoc();

进一步的代码我只依赖于Doc公开的方面,这使得代码在你决定将来编写时甚至可以工作:

Doc mydoc = new ComplexDoc();

差异的一个很好的例子是List,它至少有两个实现:

ArrayList
LinkedList

如果你写:

List list = new ArrayList();

您可以稍后用以下内容替换它:

List list = new LinkedList();

不破坏依赖于变量list的代码(假设您没有使用强制转换或反射来访问list的实现特定功能)。

答案 3 :(得分:0)

在系统中依赖抽象类型(接口或抽象类)通常是一种好习惯。

在你的例子中,你确实可以写:

SimpleDoc mydoc = new SimpleDoc()

但问题是使用mydoc的代码将取决于具体类型SimpleDoc。这不一定是一个问题,但是,假设您创建Doc的新实现,比如说ComplexDoc

您将声明更改为:

ComplexDoc mydoc = new ComplexDoc();

现在,您传递mydoc的所有场所方法也必须更改。

但是,如果您首先使用Doc,则只需进行一次更改:

Doc mydoc = ComplexDoc();

当您使用Collections API时,此功能特别有用,通常可以切换另一个实现或在测试用例中使用Mocking。

相关问题