我曾多次看到有人提到这一点,但我不清楚这是什么意思。你什么时候,为什么要这么做?

我知道接口是做什么的,但我不清楚这一点的事实使我认为我错过了正确使用它们。

如果你要这样做

IInterface classRef = new ObjectWhatever()

你可以使用任何实现IInterface的类吗?你什么时候需要这样做?我能想到的唯一一件事是,如果你有一个方法,你不确定什么对象将被传递,除了它实现IInterface。我不知道你需要多久做一次。

另外,如何编写一个方法来接受实现接口的对象呢?这可能吗?


当前回答

当您拥有一组类似的类时,它使您的代码更具可扩展性,更容易维护。我是一个初级程序员,所以我不是专家,但我刚刚完成了一个需要类似东西的项目。

我从事与运行医疗设备的服务器对话的客户端软件工作。我们正在开发这种设备的新版本,其中有一些新组件,客户必须不时进行配置。有两种类型的新组件,它们是不同的,但也非常相似。基本上,我必须创建两个配置表单,两个列表类,所有东西都要创建两个。

我决定最好是为每个控件类型创建一个抽象基类,它可以容纳几乎所有的实际逻辑,然后是派生类型,以处理两个组件之间的差异。然而,如果我不得不一直担心类型,基类就不能在这些组件上执行操作(好吧,它们可以,但每个方法中都有一个“if”语句或开关)。

我为这些组件定义了一个简单的接口,所有基类都与该接口对话。现在当我改变一些东西,它几乎“只是工作”在任何地方,我没有代码复制。

其他回答

我是这个问题的后来者,但我想在这里提到的是,在GoF (Gang of Four)设计模式一书中,“为接口编程,而不是为实现编程”这一行有一些很好的讨论。

它在第18页说:

针对接口编程,而不是针对实现编程 不要将变量声明为特定具体类的实例。相反,只提交到由抽象类定义的接口。你会发现这是本书设计模式的一个共同主题。

在此之上,它是这样开始的:

仅根据抽象类定义的接口来操作对象有两个好处: 客户端仍然不知道他们使用的对象的具体类型,只要对象遵循客户端期望的接口。 客户端仍然不知道实现这些对象的类。客户端只知道定义接口的抽象类。

So in other words, don't write it your classes so that it has a quack() method for ducks, and then a bark() method for dogs, because they are too specific for a particular implementation of a class (or subclass). Instead, write the method using names that are general enough to be used in the base class, such as giveSound() or move(), so that they can be used for ducks, dogs, or even cars, and then the client of your classes can just say .giveSound() rather than thinking about whether to use quack() or bark() or even determine the type before issuing the correct message to be sent to the object.

问:——……“你能使用任何实现接口的类吗?” A:是的。 问:——……“你什么时候需要这样做?” 答:-每次你都需要一个实现接口的类。

注意:我们不能实例化一个没有被类实现的接口- True。

为什么? 因为接口只有方法原型,没有定义(只有函数名,没有它们的逻辑)

AnIntf anInst = new class(); //我们可以这样做,只有当类实现AnIntf。 // anInst将有类引用。


注意:现在我们可以理解如果Bclass和Cclass实现相同的Dintf会发生什么。

Dintf bInst = new Bclass();  
// now we could call all Dintf functions implemented (defined) in Bclass.

Dintf cInst = new Cclass();  
// now we could call all Dintf functions implemented (defined) in Cclass.

我们拥有:相同的接口原型(接口中的函数名),调用不同的实现。

参考书目: 原型——维基百科

面向接口编程非常棒,它促进了松耦合。正如@lassevk提到的,控制反转是一个很好的应用。

此外,研究SOLID原则。这是一个系列视频

它通过硬编码(强耦合示例),然后查看接口,最后进展到IoC/DI工具(NInject)。

为了补充现有的帖子,当开发人员同时在不同的组件上工作时,有时对接口进行编码有助于大型项目。您所需要做的就是预先定义接口并为它们编写代码,而其他开发人员则为您正在实现的接口编写代码。

假设你有一个名为“Zebra”的产品,可以通过插件进行扩展。它通过在某个目录中搜索dll来查找插件。它加载所有这些dll,并使用反射来查找实现IZebraPlugin的任何类,然后调用该接口的方法来与插件通信。

这使得它完全独立于任何特定的插件类——它不关心类是什么。它只关心它们是否满足接口规范。

接口是这样定义可扩展性点的一种方式。与接口对话的代码是松散耦合的——事实上,它与任何其他特定的代码根本不耦合。它可以与多年后由从未见过原始开发人员的人编写的插件进行互操作。

你可以使用一个带有虚函数的基类——所有的插件都是从基类派生的。但这有很大的限制,因为一个类只能有一个基类,而它可以实现任意数量的接口。