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

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

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

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


当前回答

扩展一下Larsenal所说的。接口是所有实现类都必须遵循的契约。因此,您可以使用一种称为契约编程的技术。这允许您的软件变得独立于实现。

其他回答

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

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

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

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

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

我喜欢军队的比喻。

中士不在乎你是软件开发人员、音乐家还是律师。 你被当作士兵对待。

对于中士来说,不去操心与他一起工作的人的具体细节更容易, 把每个人都当作抽象的士兵(…如果他们表现得不像孩子,就要惩罚他们)。

人们像士兵一样行动的能力被称为多态性。

接口是帮助实现多态的软件结构。

为了实现简单,需要抽象细节,这就是你问题的答案。

Polymorphism, which etymologically means "many forms," is the ability to treat an object of any subclass of a base class as if it were an object of the base class. A base class has, therefore, many forms: the base class itself, and any of its subclasses. (..) This makes your code easier for you to write and easier for others to understand. It also makes your code extensible, because other subclasses could be added later to the family of types, and objects of those new subclasses would also work with the existing code.

当您希望定义对象可以显示的行为时,通常会使用接口。

在. net世界中,一个很好的例子是IDisposable接口,它用于任何使用必须手动释放的系统资源的Microsoft类。它要求实现它的类具有Dispose()方法。

Dispose()方法也被VB的using语言构造调用。NET和c#,只适用于IDisposables)

请记住,您可以通过使用诸如TypeOf…之类的构造来检查对象是否实现了特定的接口。Is (VB.NET), Is (c#), instanceof (Java),等等…

如果浏览. 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.

一个代码示例(结合了Andrew的代码和我的额外的关于“接口的目的是什么”的代码),也说明了为什么在不支持多重继承的语言(c#和java)上接口而不是抽象类:

interface ILogger
{
    void Log();
}
class FileLogger : ILogger
{
    public void Log() { }
}
class DataBaseLogger : ILogger
{
    public void Log() { }
}
public class MySpecialLogger : SpecialLoggerBase, ILogger
{
    public void Log() { }
}

注意,FileLogger和DataBaseLogger不需要接口(可以是Logger的抽象基类)。但是考虑到您需要使用第三方记录器,它迫使您使用基类(假设它公开了您需要使用的受保护的方法)。由于语言不支持多重继承,您将无法使用抽象基类方法。

底线是:尽可能使用接口来获得代码的额外灵活性。您的实现不那么受约束,因此它能更好地适应变化。