2012-02-26 68 views
6

可能重复:
Interfaces: Why can't I seem to grasp them?
Why would I want to use Interfaces?为什么我需要界面?

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

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

--Thx提前。

注:我问在.NET(C#)语言的背景下,这个问题

EDIT1:现在每当我试图学习的界面我的头脑告诉我 - >“哥们你要在一张白纸上画出一个人的身体“但是你需要另一张白纸,在那里你必须再画出轮廓,画出所有身体部位的颜色给他们以获得真实的照片。”所以我为什么要浪费第一张白纸大纲

+0

这可能有助于:interfaces描述* p​​eripheral *属性,抽象类定义* core *函数。 – Jason 2012-02-26 09:19:06

+0

如果你想让你的项目支持不同的数据库。以便客户端可以在将来改变他的数据库我们使用接口包含属性程序在类文件中不会改变对象........ – 2012-02-26 09:19:24

+0

有几十个这个问题的潜在重复...这里有几个:[1 ](http://stackoverflow.com/questions/240152/why-would-i-want-to-use-interfaces),[2](http://stackoverflow.com/questions/3355408/explaining-interfaces-to -students),[3](http://stackoverflow.com/questions/122883/interfaces-why-cant-i-seem-to-grasp-them) – 2012-02-26 11:23:51

回答

12

理解接口最简单的方法是它们允许不同的对象暴露COMMON功能。这使得程序员可以编写更简单,更短的代码来编写接口,然后只要对象实现该接口就可以工作。

数据库提供:

有许多不同的数据库供应商中,MySQL,MSSQL,Oracle等。然而所有数据库对象可以做同样的事情,所以你会发现数据库对象的多个接口。如果一个对象实现了IDBConnection,那么它将暴露方法Open()和Close()。所以如果我希望我的程序是数据库提供者不可知的,我就编程到接口而不是特定的提供者。

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

见编程接口(的IDbConnection),我现在就可以在我的配置换出任何数据提供者,但我的代码保持完全相同的。这种灵活性非常有用且易于维护。这样做的缺点是我只能执行'通用'数据库操作,可能无法充分利用每个特定提供商提供的优势,因此编程中的所有内容都有所折衷,您必须确定哪种方案最有利于您。

类别:

如果您发现几乎所有的收藏品实现此接口称为IEnumerable的。 IEnumerable返回具有MoveNext(),Current和Reset()的IEnumerator。这使C#可以轻松移动您的集合。它可以做到这一点的原因是因为它暴露IEnumerable接口,它知道对象公开它需要通过它的方法。这有两件事。 1)foreach循环现在将知道如何枚举集合,并且2)现在您可以将强大的LINQ表达式应用于您的集合。同样,接口在这里非常有用的原因是因为所有集合在COMMON中都有一些东西,所以它们可以通过。每个集合都可以通过不同的方式移动(链接列表vs数组),但接口的美妙之处在于,实现对于接口的消费者而言是隐藏的并且不相关的。 MoveNext()为您提供了集合中的下一个项目,不管它如何实现。相当不错,是吧?

多态性

当你设计自己的接口,你只需要问自己一个问题。这些东西有什么共同点?一旦你找到了对象共享的所有东西,你就可以将这些属性/方法抽象成一个接口,以便每个对象都可以继承它。然后您可以使用一个界面针对多个对象进行编程。

当然,我必须给我最喜欢的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 
} 

你可以看到,即使这些动物以不同的方式执行每一个动作,我可以在一个统一的编程模型,对他们的一切,这只是接口的众多优势之一。

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

希望这会有所帮助。

+2

优秀的答案。 – 2012-06-14 23:42:58

+0

使用接口背后原理的最佳解释之一。 – rajibdotnet 2014-05-10 18:34:29

+0

收藏答案。 +1。 – Jogi 2016-05-13 08:00:46

6

一个接口是一个合同该类可以做什么,这意味着一个类可以实现多个合同秒。

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

扩展类获取现有对象并添加/更改功能,每个类只能扩展一个父类。

如果您想描述如何在没有定义具体实现的情况下采取行动,您将使用合同(接口)。这个契约可以由任何其他实现所定义的方法/属性的类来实现。

如果您想先指定功能的一部分,然后添加到其上,则可以使用抽象类。

编辑:考虑一下:

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

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

prehaps这里更好的办法是使用说明,一般什么东西,存储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

+0

感谢您的回答。但是,如果你阅读我的新编辑,你会明白我心中发生了什么。如果你给我一些例子,这将有所帮助。 Thx – 2012-02-26 09:50:58

+0

看到我在这里编辑一个场景,基本上有时你可能不想/不需要知道如何实现某些东西,所以你只要求任何满足特定合同的东西。 – 2012-02-26 10:08:22