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

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

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

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


当前回答

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

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

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

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

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

其他回答

与任何为系统增加灵活性的编程技术一样,接口也增加了一定程度的复杂性。它们通常都很好,而且你可以在任何地方使用它(你可以为你的所有类创建一个接口)——但是这样做,你会创建一个更复杂的系统,更难维护。

像往常一样,这里有一个权衡:灵活性胜过可维护性。哪个更重要?没有答案——这取决于项目本身。但是请记住,每个软件都需要维护……

所以我的建议是:在真正需要接口之前不要使用它们。(使用Visual Studio,你可以在2秒内从现有的类中提取一个接口——所以不要着急。)

话虽如此,你什么时候需要创建一个接口呢?

当我重构一个突然需要处理两个或多个类似类的方法时,我就会这样做。然后创建一个接口,将该接口分配给两个(或多个)类似的类,并更改方法参数类型(将类类型替换为接口类型)。

它是有效的:o)

一个例外:当我模拟对象时,接口更容易使用。我经常为此创建接口。

PS:当我写“接口”时,我的意思是:“任何基类的接口”,包括纯接口类。请注意,抽象类通常比纯接口更好,因为您可以向它们添加逻辑。

此致,Sylvain。

别太担心。很多开发人员很少需要编写接口。您将经常使用. 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就有效。它在不了解任何其他课程的情况下运行得很好。”

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

当相同功能的实现不同时使用接口。

当你需要共享一个公共的具体实现时,使用一个抽象/基类。