我一直在研究接口和一个简单的外行人对它究竟是什么的解释。在书籍海洋中寻找由于某些原因,人们喜欢使用过于复杂的解释和行话来解释真正简单的概念(猜测它会让他们感觉很大)而且我有直觉感觉在这种情况下是相同的。
所以从我能掌握的,接口似乎只是一种方法来保留方法名称,它们的返回类型(如果有的话),以及它们接受的参数的类型和数量。所以当一个类实现一个接口(或接口)时,它被迫从接口定义每个方法的主体。我是这个人的鼻子还是我需要继续挖掘?
P.S。我知道javascript不支持接口,但我仍然需要理解这个概念,因为有很多地方可以显示如何在一定程度上模拟。
答案 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
界面,那么分离的任务就变得非常简单。