接口:简化

时间:2012-03-21 17:13:05

标签: c# java javascript c++ interface

我一直在研究接口和一个简单的外行人对它究竟是什么的解释。在书籍海洋中寻找由于某些原因,人们喜欢使用过于复杂的解释和行话来解释真正简单的概念(猜测它会让他们感觉很大)而且我有直觉感觉在这种情况下是相同的。

所以从我能掌握的,接口似乎只是一种方法来保留方法名称,它们的返回类型(如果有的话),以及它们接受的参数的类型和数量。所以当一个类实现一个接口(或接口)时,它被迫从接口定义每个方法的主体。我是这个人的鼻子还是我需要继续挖掘?

P.S。我知道javascript不支持接口,但我仍然需要理解这个概念,因为有很多地方可以显示如何在一定程度上模拟。

9 个答案:

答案 0 :(得分:10)

  

出于某种原因,人们喜欢使用过于复杂的解释和行话来解释真正简单的概念(猜测它会让他们觉得很大)

考虑避免编辑评论,这些评论会给那些试图帮助你的人带来不良动机。 这是让人们帮助你的一种非常糟糕的方式。

  

接口似乎只是一种保留方法名称,返回类型(如果有)以及它们所需的参数类型和数量的方法。因此,当一个类实现一个接口(或接口)时,它被迫从接口定义每个方法的主体。我是这个人的鼻子还是我需要继续挖掘?

你走在正确的轨道上,但你错了细节。例如,在C#中,实现类不是 required 来提供正文。例如,对应于接口方法的方法可以是抽象类中的抽象方法,该方法不具有主体。在C#中,接口可以要求除方法之外的其他成员;例如,属性,事件和索引器。

一种更简洁,更典型的方式来表达界面强加要求 类型提供成员与某些相匹配的想法签名是指接口代表合同,其实施者必须履行 。但这对于你的肠道来说可能过于复杂和粗俗。

答案 1 :(得分:9)

我解释了这个概念,让人们使用大多数人都能理解的类比 - 塑料成型。

界面以与模具提供成品形状完全相同的方式定义物体的形状。

你可以用白色塑料,蓝色塑料,环氧树脂或粘土之类的东西注入模具。

重要的是,无论它们实际上是什么,它们都具有与产品购买者完全一致的形状。

对于代码,这意味着无论使用什么代码来实现接口,它们都遵循与最终用户相同的一致合同/形状。

我希望这可能会有所帮助。

编辑 -

为了将类比扩展到抽象类,想象一下成型过程的下一步。您运行白色,蓝色和红色塑料生产运行,但是每个项目都需要在一个单独的工厂进行涂装,我们只需将它们运出。

该项目尚未完成,但确实已定义其形状。稍后有人会来填写我们工厂留空的细节。

这些物品在进入最后一个绘画步骤之前不能出售。

在代码中,接口的抽象实现提供了一些(或没有)实现,但是留下另一个后代类来完成契约,并且以同样的方式,没有人可以创建类的实例,直到合同具有已经完成。

以同样的方式,您仍然可以在代码中引用一个抽象类,就像您可以将未上漆的模具项目称为“白色模塑物品”一样枯萎或者不上漆!

修改2

这是一个简短的例子

void Main()
{
    //IMold mold = new IMold(); // error - can't create instance of an interface
    //Fruit fruit = new Fruit(); // error - can't create instance of an abstract class

    Apple apple1 = new Apple(); // good
    Orange orange1 = new Orange(); // good

    Fruit apple2 = (Fruit)apple1; // good - Apples are fruit
    Fruit orange2 = (Fruit)orange1; // good - oranges are fruit

    IFruitMold apple3 = (IFruitMold)apple2; // good - Apples fit the Mold
    IFruitMold orange3 = (IFruitMold)orange2; // good - Oranges also fit the mold


    //now I can do this:
    //Notice that `fruits` is of type IList<T> but the new is List<T>
    //This is the exact concept we are talking about
    //IList<T> is some kind of set of items that can be added or subtracted from
    //but we don't have to care about the implementation details of *HOW* this is done
    IList<IFruitMold> fruits = new List<IFruitMold>();
    fruits.add(apple3);
    fruits.add(orange3);

    foreach( var fruit in fruits )
    {
        fruit.PlasticColor.Dump(); // ok I can read
        fruit.PlasticColor = ""; // error - no Set defined in the interface

        // depending on the **implementation details** of what type of fruit this is true or false
        // we don't care in the slightest, we just care that we have some IFruitMold instances
        fruit.RequiresPainting.Dump(); 
    }
}

interface IFruitMold
{
    string PlasticColor { get; }
    bool RequiresPainting { get; }
}

abstract class Fruit : IFruitMold
{
    private string m_PlasticColor = string.Empty;
    public string PlasticColor { get; private set; }
    public abstract bool RequiresPainting { get; }
}

//notice that we only define the abstract portion of the base class
//it defined PlasticColor for us already!
//the keyword `override` is required  - it is to make it clear that 
//this member is overriding a member from it's parent.
class Apple : Fruit
{
    public override bool RequiresPainting { get { return true; } }
}

class Orange : Fruit
{
    public override bool RequiresPainting { get { return false; } }
}

答案 2 :(得分:2)

是的,简而言之,接口是声明并向其他人承诺某个类具有某些方法。

当您创建通用方法和函数时,这是很好的,您需要更抽象的设计。所有你想知道的是你的函数可以接收一个具有方法A B和C的对象。

答案 3 :(得分:2)

接口只是一个简单的空类,它显示了真实类应该看起来的合同。我认为你有这个概念。

他们没有预留任何东西(我不明白你的意思),这只是一种方式,所以当你围绕界面建立你的课程时,你已经知道你的课程将如何。而且你也可以知道它有哪些方法。

答案 4 :(得分:2)

  

当一个类实现一个接口(或接口)时,它被迫从接口定义每个方法的主体。

是。接口是合同。他们让其他人知道你的类实现了某些功能。

答案 5 :(得分:2)

我会说它不仅仅是保留方法名称,它是一种方法来制定方法将存在的方式,并且调用者不需要知道它的作用,但它仍然可以被称为

一个很好的例子是钢笔和铅笔都可以使用写入方法实现Iwriter接口但是无论谁调用write方法都不需要知道一个人使用墨水而一个人使用铅,调用者只知道它是要写在纸上的文字。

答案 6 :(得分:1)

接口提供与一组对象的统一交互方式。

无论对象是什么,如果它实现了接口,我们知道它将响应接口中定义的方法。通过这种方式,我们可以创建表示项目中不同内容的对象,并以相同的方式与它们进行交互。接口中定义的方法的实际实现可能完全不同,但它们将采用相同的输入并提供相同类型的输出。

答案 7 :(得分:1)

基本上,接口是一个契约,它可以定义属性(getter和setter)或方法(使用您需要的任何参数)。如果对象“实现”接口,则需要为接口中定义的所有属性和方法定义具体实现。

对于单元测试或Inversion of Control,容器接口确实存在,因为您可以在接口上调用方法/属性,而不了解实际实现它的对象。

答案 8 :(得分:1)

接口用于在一组完全不相关的对象之间提供通用功能。

让我们说我们有一堆动物物品,我们需要将宠物与那些宠物分开。如果我们强制执行一项合同,使得所有宠物动物都需要实现IPet界面,那么分离的任务就变得非常简单。