接口:简化

zer*_*ero 5 javascript c# c++ java interface

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

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

ps我知道javascript不支持接口,但是我仍然需要理解这个概念,因为有很多地方显示了如何模拟到一定程度.

Eri*_*ert 10

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

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

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

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

更简洁和典型的方式来表达接口征收的理念要求,一个类型的供应成员一致肯定,签名是说,该接口表示合同必须履行它的实施者.但这对于你的肠道来说可能过于复杂和粗俗.


asa*_*yer 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; } }
}
Run Code Online (Sandbox Code Playgroud)