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

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

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

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


当前回答

As several people have probably already answered, interfaces can be used to enforce certain behaviors between classes that will not implement those behaviors the same way. So by implementing an interface you are saying that your class has the behavior of the interface. The IAnimal interface would not be a typical interface because Dog, Cat, Bird, etc. classes are types of animals, and should probably extend it, which is a case of inheritance. Instead, an interface would be more like animal behavior in this case, such as IRunnable, IFlyable, ITrainable, etc.

接口有很多好处,其中一个关键就是可插拔性。例如,声明一个具有List参数的方法将允许传入实现List接口的任何东西,允许开发人员在以后删除和插入不同的列表,而不必重写大量代码。

您可能永远不会使用接口,但如果您正在从头开始设计一个项目,特别是某种类型的框架,您可能会想要熟悉它们。

我建议大家阅读Coad、Mayfield和Kern撰写的《Java设计》中关于接口的章节。它们比一般的介绍性文本解释得好一点。如果你不使用Java,你可以只阅读本章的开头,主要是一些概念。

其他回答

当您希望能够对多个类型使用单个变量,但所有这些类型通过接口声明实现相同的方法时,Jimmy是正确的。然后你可以在接口类型变量上调用它们的main方法。

然而,使用接口还有第二个原因。当项目架构师和实现编码员是不同的人时,或者有几个实现编码员和一个项目经理。负责人可以编写一大堆接口,并查看系统的互操作,然后让开发人员用实现类填充接口。这是确保多人编写兼容类的最佳方法,而且他们可以并行地完成。

当您成为库开发人员(为其他编码员编写代码的人)时,接口将变得很明显。我们中的大多数人都是从应用程序开发人员开始的,我们使用现有的api和编程库。

同样的,接口是一种契约,还没有人提到接口是一种使代码的某些部分稳定的好方法。当它是一个团队项目时(或者当您正在开发其他开发人员使用的代码时),这尤其有用。所以,这里有一个具体的场景:

当您在团队中开发代码时,其他人可能会使用您编写的代码。当他们为你的(稳定的)接口编写代码时,他们会非常高兴,而当你可以自由地改变你的实现(隐藏在接口后面)而不破坏你团队的代码时,你也会非常高兴。它是信息隐藏的一种变体(接口是公开的,实现对客户端程序员隐藏)。阅读更多关于受保护的变种。

另请参阅有关接口编码的相关问题。

如果浏览. net Framework程序集并深入到任何标准对象的基类中,您将注意到许多接口(名为ISomeName的成员)。

Interfaces are basically for implementing frameworks, large or small. I felt the same way about interfaces until I wanted to write a framework of my own. I also found that understanding interfaces helped me learn frameworks much more rapidly. The moment that you want to write a more elegant solution for just about anything, you will find that an interface makes a lot of sense. It's like a method of letting a class put on the appropriate clothes for the job. More importantly, interfaces allow systems to become much more self-documenting, because complex objects become less complex when the class implements interfaces, which helps to categorize its functionality.

类在希望能够显式或隐式地参与框架时实现接口。例如,IDisposable是一个公共接口,它为流行且有用的Dispose()方法提供方法签名。在框架中,您或其他开发人员需要知道的关于类的所有信息是,如果它实现了IDisposable,那么您就知道((IDisposable)myObject). dispose()可用于清理目的。

经典示例:在没有实现IDisposable接口的情况下,你不能在c#中使用"using()"关键字构造,因为它要求任何指定为参数的对象都可以隐式转换为IDisposable。

复杂的例子: 一个更复杂的例子是System.ComponentModel.Component类。这个类同时实现了IDisposable和IComponent。大多数(如果不是全部的话)具有与之关联的可视化设计器的. net对象实现了IComponent,以便IDE能够与组件交互。

CONCLUSION: As you become more familiar with the .NET Framework, the first thing you will do when encountering a new class in the Object Browser or within the .NET Reflector (free) tool (http://www.red-gate.com/products/reflector/) is to check to see which class it inherits from and also the interfaces that it implements. .NET Reflector is even better than the Object Browser because it lets you see the Derived classes as well. That allows you to learn about all objects that derive from a particular class, thereby potentially learning about framework functionality that you did not know existed. This is particularly significant when updated or new namespaces are added to the .NET Framework.

假设你正在制作一款第一人称射击游戏。玩家有多种枪可供选择。

我们可以有一个接口Gun,它定义了函数shoot()。

我们需要不同的子类枪类,即霰弹枪狙击手等。

ShotGun implements Gun{
    public void shoot(){
       \\shotgun implementation of shoot.
    } 
}

Sniper implements Gun{
    public void shoot(){
       \\sniper implementation of shoot.
    } 
}

射击类

射手把所有的枪都装在他的盔甲里。让我们创建一个List来表示它。

List<Gun> listOfGuns = new ArrayList<Gun>();

射手在需要时使用switchGun()函数循环使用他的枪。

public void switchGun(){
    //code to cycle through the guns from the list of guns.
    currentGun = //the next gun in the list.
}

我们可以使用上面的函数设置当前的Gun,当调用fire()时,简单地调用shoot()函数。

public void fire(){
    currentGun.shoot();
}

shoot函数的行为将根据Gun接口的不同实现而有所不同。

结论

当一个类函数依赖于来自另一个类的函数时,创建一个接口,而另一个类根据实现的类的实例(对象)改变其行为。

例如,Shooter类的fire()函数期望枪械(Sniper, ShotGun)实现shoot()函数。 所以如果我们换枪开火。

shooter.switchGun();
shooter.fire();

我们已经改变了fire()函数的行为。

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

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

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

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