接口和抽象类的区别

上传人:子 文档编号:43793032 上传时间:2018-06-07 格式:DOC 页数:23 大小:52KB
返回 下载 相关 举报
接口和抽象类的区别_第1页
第1页 / 共23页
接口和抽象类的区别_第2页
第2页 / 共23页
接口和抽象类的区别_第3页
第3页 / 共23页
接口和抽象类的区别_第4页
第4页 / 共23页
接口和抽象类的区别_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《接口和抽象类的区别》由会员分享,可在线阅读,更多相关《接口和抽象类的区别(23页珍藏版)》请在金锄头文库上搜索。

1、接口和抽象类的区别接口和抽象类的区别3.1 相同点都不能被直接实例化,都可以通过继承实现其抽象方法。都是面向抽象编程的技术基础,实现了诸多的设计模式。3.2 不同点接口支持多继承;抽象类不能实现多继承。接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员。接口是一组行为规范;抽象类是一个不完全的类,着重族的概念。接口可以用于支持回调;抽象类不能实现回调,因为继承不支持。接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。例如,Struct 就可以继承接口,而

2、不能继承类。通过相同与不同的比较,我们只能说接口和抽象类,各有所长,但无优略。在实际的编程实践中,我们要视具体情况来酌情量才,但是以下的经验和积累,或许能给大家一些启示,除了我的一些积累之外,很多都来源于经典,我相信经得起考验。所以在规则与场合中,我们学习这些经典,最重要的是学以致用,当然我将以一家之言博大家之笑,看官请继续。3.3 规则与场合请记住,面向对象思想的一个最重要的原则就是:面向接口编程。借助接口和抽象类,23 个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:面向抽象编程。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。接口着重于 CAN-DO

3、 关系类型,而抽象类则偏重于 IS-A 式的关系;接口多定义对象的行为;抽象类多定义对象的属性;接口定义可以使用 public、protected、internal 和 private修饰符,但是几乎所有的接口都定义为 public,原因就不必多说了。“接口不变” ,是应该考虑的重要因素。所以,在由接口增加扩展时,应该增加新的接口,而不能更改现有接口。尽量将接口设计成功能单一的功能块,以.NET Framework 为例,IDisposable、IDisposable、IComparable、IEquatable、IEnumerable 等都只包含一个公共方法。接口名称前面的大写字母“I”是一

4、个约定,正如字段名以下划线开头一样,请坚持这些原则。在接口中,所有的方法都默认为 public。如果预计会出现版本问题,可以创建“抽象类” 。例如,创建了狗(Dog) 、鸡(Chicken)和鸭(Duck) ,那么应该考虑抽象出动物(Animal)来应对以后可能出现风马牛的事情。而向接口中添加新成员则会强制要求修改所有派生类,并重新编译,所以版本式的问题最好以抽象类来实现。从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。对抽象类不能使用 new 关键字,也不能被密封,原因是抽象类不能被实例化。在抽象方法声明中不能使用 static 或 virtual 修饰符。*我想,对于

5、各位使用面向对象编程语言的程序员来说, “接口”这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,作为程序员,一定经常听到“面向接口编程”这个短语,那么它是什么意思?有什么思想内涵?和面向对象编程是什么关系?本文将一一解答这些疑问。1.面向接口编程和面向对象编程是什么关系首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分。或者说,它是面向对象编程体系中的思想精髓之一。2.接口的本质接口,在表面上是由几个没有主体代码的方法定义组成的集合体,有

6、唯一的名称,可以被类或其他接口所实现(或者也可以说继承) 。它在形式上可能是如下的样子:interface InterfaceNamevoid Method1();void Method2(int para1);void Method3(string para2,string para3);那么,接口的本质是什么呢?或者说接口存在的意义是什么。我认为可以从以下两个视角考虑:1)接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是则必须能”的理念。例如,在自然界中,人都能吃饭,即“如果你是人,则必须能吃饭”。那么模拟到计算机程序中,就应该有一个 IPers

7、on(习惯上,接口名由“I”开头)接口,并有一个方法叫 Eat(),然后我们规定,每一个表示“人”的类,必须实现 IPerson 接口,这就模拟了自然界“如果你是人,则必须能吃饭”这条规则。从这里,我想各位也能看到些许面向对象思想的东西。面向对象思想的核心之一,就是模拟真实世界,把真实世界中的事物抽象成类,整个程序靠各个类的实例互相通信、互相协作完成系统功能,这非常符合真实世界的运行状况,也是面向对象思想的精髓。2)接口是在一定粒度视图上同类事物的抽象表示。注意这里我强调了在一定粒度视图上,因为“同类事物”这个概念是相对的,它因为粒度视图不同而不同。例如,在我的眼里,我是一个人,和一头猪有本质

8、区别,我可以接受我和我同学是同类这个说法,但绝不能接受我和一头猪是同类。但是,如果在一个动物学家眼里,我和猪应该是同类,因为我们都是动物,他可以认为“人”和“猪”都实现了 IAnimal 这个接口,而他在研究动物行为时,不会把我和猪分开对待,而会从“动物”这个较大的粒度上研究,但他会认为我和一棵树有本质区别。现在换了一个遗传学家,情况又不同了,因为生物都能遗传,所以在他眼里,我不仅和猪没区别,和一只蚊子、一个细菌、一颗树、一个蘑菇乃至一个 SARS 病毒都没什么区别,因为他会认为我们都实现了 IDescendable 这个接口(注:descend vi. 遗传) ,即我们都是可遗传的东西,他不

9、会分别研究我们,而会将所有生物作为同类进行研究,在他眼里没有人和病毒之分,只有可遗传的物质和不可遗传的物质。但至少,我和一块石头还是有区别的。可不幸的事情发生了,某日,地球上出现了一位伟大的人,他叫列宁,他在熟读马克思、恩格斯的辩证唯物主义思想巨著后,颇有心得,于是他下了一个著名的定义:所谓物质,就是能被意识所反映的客观实在。至此,我和一块石头、一丝空气、一条成语和传输手机信号的电磁场已经没什么区别了,因为在列宁的眼里,我们都是可以被意识所反映的客观实在。如果列宁是一名程序员,他会这么说:所谓物质,就是所有同时实现了“IReflectabe”和“IEsse”两个接口的类所生成的实例。 (注:r

10、eflect v. 反映 esse n. 客观实在)也许你会觉得我上面的例子像在瞎掰,但是,这正是接口得以存在的意义。面向对象思想和核心之一叫做多态性,什么叫多态性?说白了就是在某个粒度视图层面上对同类事物不加区别的对待而统一处理。而之所以敢这样做,就是因为有接口的存在。像那个遗传学家,他明白所有生物都实现了 IDescendable 接口,那只要是生物,一定有 Descend()这个方法,于是他就可以统一研究,而不至于分别研究每一种生物而最终累死。可能这里还不能给你一个关于接口本质和作用的直观印象。那么在后文的例子和对几个设计模式的解析中,你将会更直观体验到接口的内涵。3.面向接口编程综述通

11、过上文,我想大家对接口和接口的思想内涵有了一个了解,那么什么是面向接口编程呢?我个人的定义是:在系统分析和架构中,分清层次和依赖关系,每个层次不是直接向其上层提供服务(即不是直接实例化在上层中) ,而是通过定义一组接口,仅向上层暴露其接口功能,上层对于下层仅仅是接口依赖,而不依赖具体类。这样做的好处是显而易见的,首先对系统灵活性大有好处。当下层需要改变时,只要接口及接口功能不变,则上层不用做任何修改。甚至可以在不改动上层代码时将下层整个替换掉,就像我们将一个WD 的 60G 硬盘换成一个希捷的 160G 的硬盘,计算机其他地方不用做任何改动,而是把原硬盘拔下来、新硬盘插上就行了,因为计算机其他

12、部分不依赖具体硬盘,而只依赖一个 IDE 接口,只要硬盘实现了这个接口,就可以替换上去。从这里看,程序中的接口和现实中的接口极为相似,所以我一直认为,接口(interface)这个词用的真是神似!使用接口的另一个好处就是不同部件或层次的开发人员可以并行开工,就像造硬盘的不用等造 CPU 的,也不用等造显示器的,只要接口一致,设计合理,完全可以并行进行开发,从而提高效率。本篇文章先到这里。最后我想再啰嗦一句:面向对象的精髓是模拟现实,这也可以说是我这篇文章的灵魂。所以,多从现实中思考面向对象的东西,对提高系统分析设计能力大有脾益。下篇文章,我将用一个实例来展示接口编程的基本方法。而第三篇,我将解

13、析经典设计模式中的一些面向接口编程思想,并解析一下.NET 分层架构中的面向接口思想。对本文的补充:仔细看了各位的回复,非常高兴能和大家一起讨论技术问题。感谢给出肯定的朋友,也要感谢提出意见和质疑的朋友,这促使我更深入思考一些东西,希望能借此进步。在这里我想补充一些东西,以讨论一些回复中比较集中的问题。1.关于“面向接口编程”中的“接口”与具体面向对象语言中“接口”两个词看到有朋友提出“面向接口编程”中的“接口”二字应该比单纯编程语言中的 interface 范围更大。我经过思考,觉得很有道理。这里我写的确实不太合理。我想,面向对象语言中的“接口”是指具体的一种代码结构,例如 C#中用 int

14、erface 关键字定义的接口。而“面向接口编程”中的“接口”可以说是一种从软件架构的角度、从一个更抽象的层面上指那种用于隐藏具体底层类和实现多态性的结构部件。从这个意义上说,如果定义一个抽象类,并且目的是为了实现多态,那么我认为把这个抽象类也称为“接口”是合理的。但是用抽象类实现多态合理不合理?在下面第二条讨论。概括来说,我觉得两个“接口”的概念既相互区别又相互联系。 “面向接口编程”中的接口是一种思想层面的用于实现多态性、提高软件灵活性和可维护性的架构部件,而具体语言中的“接口”是将这种思想中的部件具体实施到代码里的手段。2.关于抽象类与接口看到回复中这是讨论的比较激烈的一个问题。很抱歉我

15、考虑不周没有在文章中讨论这个问题。我个人对这个问题的理解如下:如果单从具体代码来看,对这两个概念很容易模糊,甚至觉得接口就是多余的,因为单从具体功能来看,除多重继承外(C#,Java 中),抽象类似乎完全能取代接口。但是,难道接口的存在是为了实现多重继承?当然不是。我认为,抽象类和接口的区别在于使用动机。使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。所以,如果你在为某个地方该使用接口还是抽象类而犹豫不决时,那么可以想想你的动机是什么。看到有朋友对 IPerson 这个接口的质疑,我个人的理解是,IPerson这个接口该不该定义,关键看具体应用中是怎么个情况。如果我们的项目中有

16、Women 和 Man,都继承 Person,而且 Women 和 Man 绝大多数方法都相同,只有一个方法 DoSomethingInWC()不同(例子比较粗俗,各位见谅) ,那么当然定义一个 AbstractPerson 抽象类比较合理,因为它可以把其他所有方法都包含进去,子类只定义DoSomethingInWC() ,大大减少了重复代码量。但是,如果我们程序中的 Women 和 Man 两个类基本没有共同代码,而且有一个 PersonHandle 类需要实例化他们,并且不希望知道他们是男是女,而只需把他们当作人看待,并实现多态,那么定义成接口就有必要了。总而言之,接口与抽象类的区别主要在于使用的动机,而不在于其本身。而一个东西该定义成抽象类还是接口,要根据具体

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号