0

我最近在“Professional C# 4 and .NET 4”中读到:

你永远不能实例化一个接口。

但我会定期看到这样的事情:

IQuadrilateral myQuad;

直接使用接口有什么限制(没有从接口继承的类)?我怎么能使用这样的对象(如果它们甚至可以被称为对象)?

例如,不使用派生自 IQuadrilateral 的 Square 类,我可以在多大程度上摆脱创建像 IQuadrilateral myQuad 这样的接口?

由于接口不实现方法,我认为我不能对它们使用任何方法。我认为接口没有字段(只有属性),所以我不确定如何使用它们存储数据。

4

3 回答 3

4

答案很简单,你不能实例化一个接口。

您提供的示例不是实例化接口的示例,您只是定义类型的局部变量IQuadrilateral

要实例化接口,您必须这样做:

IQuadrilateral myQuad = new IQuadrilateral();

这是不可能的,因为IQuadrilateral没有构造函数。

这是完全有效的:

IQuadrilateral myQuad = new Square();

但是您不是在启动IQuadrilateral,而是在启动Square并将其分配给类型为 的变量IQuadrilateral

中可用myQuad的方法将是接口中定义的方法,但实现将基于Square. 除非您强制转换为变量,否则Square不属于接口的任何其他方法都IQuadrilateral将不可用。myQuadSquare

于 2012-12-10T18:16:49.567 回答
2

您不能创建接口的实例。

您显示的代码定义了一个类型为 的变量IQuadrilateral。此变量指向的实际实例将始终是实现此接口的具体类。

于 2012-12-10T18:13:53.040 回答
0

背景知识

将接口视为合同。在两个人之间的合同中,它定义了所涉及的各方的能力和期望。在编程中,它的工作方式相同。接口定义了期望什么,必须存在什么才能符合该接口。因此,由于它只定义了预期的内容,它本身并没有提供实现,可以说是“幕后代码”。

属性的行为类似于字段,但允许您在有人为其分配值或读取值时进行拦截。您也可以拒绝读取或写入它,这是您定义属性时的选择。因此,接口使用属性而不是字段。由于“合同”只是定义应该存在的属性(名称和类型),并且如果它应该允许读取或写入功能,则由实现者来提供它。

以.NET 框架中的IEnumerator接口为例。该接口旨在允许对对象集合进行迭代。目的不是更改项目或随机访问它们,它只是为了获取对象 A 并根据需要多次移动到下一个、下一个、下一个。许多集合类型类实现了这一点:Queue、ArrayList、SortedList、Stack 等。所有这些类型的对象都存储了许多对象,现在它们都共享一个共同的“契约”:能够逐个迭代它们。

但是,您可以看到该IEnumerator接口MoveNext()声明了一个方法。为什么?这是因为这些项目可能不会以相同的方式提供。例如,人们通常会从第一项到最后一项访问 ArrayList。但是 aStack的设计正好相反,人们可以访问最后一个对象到第一个对象。

已回答的问题

有了所有这些知识,将变量声明为接口类型而不是实现接口的类类型的局限性在于,您只能访问接口(合同)所说的应该存在的内容。但好处是您可以将任何实现该接口的类类型分配给此变量。

于 2012-12-10T18:42:36.643 回答