为什么我需要接口?

可能重复:
接口:为什么我似乎无法掌握它们?
我为什么要使用Interfaces?

我认为这个问题重复了1000次,我很抱歉再次提问。 我真的在寻找一个简单明了的答案,为什么我明确需要接口,或者如果你请解释一些我没有接口就无法实现的东西。

如果它是多重inheritance,那么我会请你给我一个简单的例子,通过它我可以理解为什么我需要接口。

– 提前。

注意:我在.NET(C#)语言的上下文中提出这个问题

编辑1 :现在,每当我尝试学习界面时,我的思绪告诉我 – >“伙计你要用白纸勾勒出某人的身体”但是你需要另一张白纸,你需要再次绘制轮廓,绘制所有身体部位填充颜​​色给他们以获得真实的图片“。那么为什么我只是为了获得轮廓而浪费第一张白纸。

理解接口的最简单方法是允许不同的对象公开COMMONfunction。 这允许程序员编写更简单,更短的代码来编程到接口,然后只要对象实现该接口就可以工作。

数据库提供商:

有许多不同的数据库提供程序,MySQL,MSSQL,Oracle等。但是,所有数据库对象都可以执行相同的操作,因此您将找到许多数据库对象的接口。 如果一个对象实现了IDBConnection,那么它会暴露方法Open()和Close()。 因此,如果我希望我的程序与数据库提供程序无关,我编程到接口而不是特定的提供程序。

IDbConnection connection = GetDatabaseConnectionFromConfig() connection.Open() // do stuff connection.Close() 

通过编程接口(IDbconnection)看到我现在可以在配置中刷出任何数据提供程序,但我的代码保持完全相同。 这种灵活性非常有用且易于维护。 这样做的缺点是我只能执行“通用”数据库操作,并且可能无法充分利用每个特定提供商提供的强度,因此在编程中您需要权衡一切,并且您必须确定哪种方案对您最有利。

类别:

如果您注意到几乎所有集合都实现了名为IEnumerable的接口。 IEnumerable返回一个IEnumerator,它有MoveNext(),Current和Reset()。 这使C#可以轻松地在您的collections中移动。 它能够做到这一点的原因是它暴露了IEnumerable接口,它知道该对象公开了它需要通过它的方法。 这样做有两件事。 1)foreach循环现在将知道如何枚举集合和2)您现在可以将强大的LINQ exprssions应用于您的集合。 接口在这里非常有用的原因是因为所有集合在COMMON中都有一些东西,它们可以被移动。 每个集合可以通过不同的方式(链表与数组)进行移动,但接口的优点在于实现是隐藏的,与接口的使用者无关。 MoveNext()为您提供集合中的下一个项目,它如何做到并不重要。 太好了,对吧?

多态性

当您设计自己的界面时,您只需要问自己一个问题。 这些东西有什么共同之处? 一旦找到对象共享的所有内容,就会将这些属性/方法抽象到接口中,以便每个对象都可以从中inheritance。 然后,您可以使用一个界面对多个对象进行编程。

当然,我必须提供我最喜欢的C ++多态示例,即动物示例。 所有动物都具有某些特征。 让我们说他们可以移动,说话,他们都有一个名字。 因为我刚刚确定了我的所有动物的共同点,我可以将这些特质抽象到IAnimal界面中。 然后我创建了一个Bear对象,一个Owl对象和一个Snake对象,它们都实现了这个接口。 您可以将实现相同接口的不同对象存储在一起的原因是接口表示IS-A重放。 熊IS-A动物,猫头鹰IS-A动物,因此我可以将它们全部收集为动物。

 var animals = new IAnimal[] = {new Bear(), new Owl(), new Snake()} // here I can collect different objects in a single collection because they inherit from the same interface foreach (IAnimal animal in animals) { Console.WriteLine(animal.Name) animal.Speak() // a bear growls, a owl hoots, and a snake hisses animal.Move() // bear runs, owl flys, snake slithers } 

你可以看到,即使这些动物以不同的方式执行每个动作,我也可以在一个统一的模型中对它们进行编程,这只是Interfaces的众多好处之一。

因此,接口最重要的事情是对象具有什么共同点,以便您可以以相同的方式对DIFFERENT对象进行编程。 节省时间,创建更灵活的应用程序,隐藏复杂性/实施,模拟现实世界的对象/情况,以及许多其他好处。

希望这可以帮助。

接口是类可以执行的契约 ,这意味着单个类可以实现多个合同。

抽象类是一个类应该如何表现的模板,每个类只能填写一个模板。

扩展类采用现有对象并添加/更改function,每个类只能扩展一个父类。

如果要在不定义特定实现的情况下描述某些操作应该如何操作,则可以使用契约(接口)。 任何其他实现定义的方法/属性的类都可以实现此契约。

如果要预先指定部分function然后添加到它上,则可以使用抽象类。

编辑:考虑一下:

您有一个应用程序需要存储一些数据Say EntityA但您可以有多种方式来存储数据(例如xml,SQL数据库,CSV等)。 您可以为这些不同的方法创建一个类来存储EntityA。 但是当你想要改变方法时,你需要在那里明确指定你想要的类型。

 public class DoStuffWithEntityA{ public void DoStuffAndStoreAsXml(EntityA entity){ /*Logic*/} public void DoStuffAndStoreAsCsv(EntityA entity){ /*Logic*/} public void DoStuffAndStoreInDatabase(EntityA entity){ /*Logic*/} } 

或许更好的方法是使用一个界面,它通常描述存储EntityA的东西是什么样的。

例如

 public interface IStoreEntityA{ void Store(EnitityA entity); } 

然后你可以说你想要在你的代码中存储EntityA的东西

 public class DoStuffWithEntityA{ private IStoreEntityA _entityAStorer; public DoStuffWithEntityA(IStoreEntityA howIStoreEntityA){ _entityAStorer = howIStoreEntityA;} public void DoStuff(EntityA entity) { //Do Stuff _entityAStorer.Store(entity); } } 

这意味着您的逻辑与存储EntityA的方式紧密相关

  • 如何将所包含的项添加到文档注释中
  • 在C#中初始化静态变量内联或静态构造函数的差异
  • Convert.ToDecimal(string)和Decimal.Parse(string)之间的区别
  • 从C#将表类型对象作为输入参数传递给Oracle中的存储过程
  • Silverlight – > WCF – >数据库 – >问题
  • 使用https的C#WebClient
  • 锁定变量应该声明为volatile吗?
  • 带有entity framework的强类型ASP.NET MVC
  • 检索SQL Server表中的特定行范围
  • 将XDocument转换为Stream
  • 将数字格式化为字符串,使用逗号代替小数