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

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

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

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


当前回答

别太担心。很多开发人员很少需要编写接口。您将经常使用. net框架中可用的接口,但如果您觉得没有必要在短时间内编写一个接口,这也没什么好奇怪的。

我经常给别人的例子是,如果你有一个帆船职业和一个毒蛇职业。它们分别继承了Boat类和Car类。现在假设您需要遍历所有这些对象并调用它们的Drive()方法。你也可以编写如下代码:

if(myObject is Boat)
    ((Boat)myObject).Drive()
else
    if (myObject is Car)
        ((Car)myObject).Drive()

这样写会简单得多:

((IDrivable)myObject).Drive()

其他回答

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

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

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

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

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

所以在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就有效。它在不了解任何其他课程的情况下运行得很好。”

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

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

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

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

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

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

它解决了一个具体的问题:

你有a b c d四种不同类型。在你的代码中,你可以这样写:

a.Process();
b.Process();
c.Process();
d.Process();

为什么不让他们实现IProcessable呢

List<IProcessable> list;

foreach(IProcessable p in list)
    p.Process();

当你添加50种类型的类,它们都做同样的事情时,这种伸缩性会更好。


另一个具体问题是:

你有没有看过System.Linq.Enumerable?它定义了大量的扩展方法,可以对实现IEnumerable的任何类型进行操作。因为任何实现IEnumerable的东西基本上都在说“我支持无序foreach类型模式中的迭代”,所以你可以为任何可枚举类型定义复杂的行为(Count、Max、Where、Select等)。