在我的开发学习中,我觉得我必须学习更多关于接口的知识。

我经常读到它们,但我似乎无法理解它们。

我读过这样的例子:动物基类,IAnimal接口的东西,如“Walk”,“Run”,“GetLegs”等-但我从来没有工作过,觉得“嘿,我应该在这里使用接口!”

我错过了什么?为什么这个概念对我来说这么难理解!我只是害怕这样一个事实,我可能从来没有意识到一个具体的需要-主要是由于一些缺失的理解他们!这让我觉得我作为一名开发人员缺少了一些东西!如果有人有过这样的经历,并取得了突破,我会很感激一些关于如何理解这个概念的建议。谢谢你!


当前回答

一些非编程示例可能帮助您了解接口在编程中的适当使用。

There's an interface between electrical devices and the electricity network - it's the set of conventions about the shape of the plugs and sockets and the voltages/currents across them. If you want to implement a new electrical device, as long as your plug follows the rules it will be able to get services from the network. This makes extensibility very easy and removes or lowers the costs of coordination: you don't have to notify the electricity provider about how your new device works and come to a separate agreement about how to plug your new device into the network.

各国都有标准的铁路轨距。这使得铺设铁轨的工程公司和建造在这些铁轨上运行的列车的工程公司之间实现了分工,并使铁路公司有可能在不重新设计整个系统的情况下更换和升级列车。

The service a business presents to a client can be described as an interface: a well defined interface emphasises the service and hides the means. When you put a letter in a mailbox, you expect the postal system to deliver the letter within a given time but you have no expectations about how the letter is delivered: you don't need to know, and the postal service has the flexibility to choose the means of delivery that best meets the requirements and current circumstances. An exception to this is the ability of customers to choose airmail - that's not the kind of interface a modern computer programmer would have designed, since it reveals too much of the implementation.

来自自然的例子:我不太喜欢eats(), makesSound(), moves()等例子。它们确实描述了行为,这是正确的,但它们没有描述交互以及它们是如何被启用的。在自然界中,使相互作用成为可能的界面的一个明显的例子是与繁殖有关的,例如一朵花为蜜蜂提供了一个特定的界面,以便授粉能够发生。

其他回答

一些非编程示例可能帮助您了解接口在编程中的适当使用。

There's an interface between electrical devices and the electricity network - it's the set of conventions about the shape of the plugs and sockets and the voltages/currents across them. If you want to implement a new electrical device, as long as your plug follows the rules it will be able to get services from the network. This makes extensibility very easy and removes or lowers the costs of coordination: you don't have to notify the electricity provider about how your new device works and come to a separate agreement about how to plug your new device into the network.

各国都有标准的铁路轨距。这使得铺设铁轨的工程公司和建造在这些铁轨上运行的列车的工程公司之间实现了分工,并使铁路公司有可能在不重新设计整个系统的情况下更换和升级列车。

The service a business presents to a client can be described as an interface: a well defined interface emphasises the service and hides the means. When you put a letter in a mailbox, you expect the postal system to deliver the letter within a given time but you have no expectations about how the letter is delivered: you don't need to know, and the postal service has the flexibility to choose the means of delivery that best meets the requirements and current circumstances. An exception to this is the ability of customers to choose airmail - that's not the kind of interface a modern computer programmer would have designed, since it reveals too much of the implementation.

来自自然的例子:我不太喜欢eats(), makesSound(), moves()等例子。它们确实描述了行为,这是正确的,但它们没有描述交互以及它们是如何被启用的。在自然界中,使相互作用成为可能的界面的一个明显的例子是与繁殖有关的,例如一朵花为蜜蜂提供了一个特定的界面,以便授粉能够发生。

它还允许您执行模拟单元测试(. net)。如果您的类使用接口,您可以在单元测试中模拟对象,并轻松地测试逻辑(无需实际触及数据库或web服务等)。

http://www.nmock.org/

把接口想象成一个契约。这是一种说法,“这些类应该遵循这些规则。”

所以在IAnimal的例子中,它是一种说,“我必须能够在实现IAnimal的类上调用Run, Walk等。”

为什么这个有用?您可能希望构建一个函数,该函数依赖于必须能够在对象上调用Run和Walk这一事实。你可以有以下内容:

public void RunThenWalk(Monkey m) {
    m.Run();
    m.Walk();
}

public void RunThenWalk(Dog d) {
    d.Run();
    d.Walk();
}

... 对所有你知道能跑能走的物体重复这一步骤。然而,在你的IAnimal接口中,你可以像下面这样定义函数:

public void RunThenWalk(IAnimal a) {
    a.Run();
    a.Walk();
}

通过根据接口编程,您实际上是信任类来实现接口的目的。所以在我们的例子中,想法是“我不在乎他们怎么跑和走,只要他们能跑和走。”只要他们履行协议,我的RunThenWalk就有效。它在不了解任何其他课程的情况下运行得很好。”

在这个相关的问题上也有很好的讨论。

作为一个。net开发人员,你完全有可能一辈子都不编写自己的接口。毕竟,没有它们,我们也活了几十年,我们的语言仍然是图灵完备的。

我不能告诉你为什么你需要接口,但我可以给你一个我们在当前项目中使用它们的列表:

在我们的插件模型中,我们通过接口加载插件,并将该接口提供给插件编写者以使其遵循。 在我们的机间消息传递系统中,消息类都实现了一个特定的接口,并使用该接口“解包装”。 我们的配置管理系统定义了一个用于设置和检索配置设置的接口。 我们使用一个接口来避免讨厌的循环引用问题。(如果没有必要,就不要这样做。)

我想如果有一个规则,那就是当你想在一个is-a关系中对几个类进行分组,但你不想在基类中提供任何实现时使用接口。

一旦你需要为你的类强制一个行为,你应该定义一个接口。

动物的行为可能包括走、吃、跑等。因此,您将它们定义为接口。

另一个实际的例子是ActionListener(或Runnable)接口。您可以在需要跟踪特定事件时实现它们。因此,您需要在类(或子类)中提供actionPerformed(Event e)方法的实现。类似地,对于Runnable接口,提供公共void run()方法的实现。

此外,您可以让任意数量的类实现这些接口。

使用接口(在Java中)的另一个实例是实现c++中提供的多重继承。