`
mypengkun
  • 浏览: 14055 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

面向接口编程详解(一)——思想基础

阅读更多

我想,对于各位使用面向对象编程语言的程序员来说,“接口”这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,作为程序员,一定经常听到“面向接口编程”这个短语,那么它是什么意思?有什么思想内涵?和面向对象编程是什么关系?本文将一一解答这些疑问。

1.面向接口编程和面向对象编程是什么关系

首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分。或者说,它是面向对象编程体系中的思想精髓之一。

2.接口的本质

接口,在表面上是由几个没有主体代码的方法定义组成的集合体,有唯一的名称,可以被类或其他接口所实现(或者也可以说继承)。它在形式上可能是如下的样子:

interface InterfaceName
{
    
void Method1();
    
void Method2(int para1);
    
void Method3(string para2,string para3);
}

 

那么,接口的本质是什么呢?或者说接口存在的意义是什么。我认为可以从以下两个视角考虑:

1)接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。

 例如,在自然界中,人都能吃饭,即“如果你是人,则必须能吃饭”。那么模拟到计算机程序中,就应该有一个IPerson(习惯上,接口名由“I”开头)接口,并有一个方法叫Eat(),然后我们规定,每一个表示“人”的类,必须实现IPerson接口,这就模拟了自然界“如果你是人,则必须能吃饭”这条规则。

从这里,我想各位也能看到些许面向对象思想的东西。面向对象思想的核心之一,就是模拟真实世界,把真实世界中的事物抽象成类,整个程序靠各个类的实例互相通信、互相协作完成系统功能,这非常符合真实世界的运行状况,也是面向对象思想的精髓。

2)接口是在一定粒度视图上同类事物的抽象表示。注意这里我强调了在一定粒度视图上,因为“同类事物”这个概念是相对的,它因为粒度视图不同而不同。

 例如,在我的眼里,我是一个人,和一头猪有本质区别,我可以接受我和我同学是同类这个说法,但绝不能接受我和一头猪是同类。但是,如果在一个动物学家眼里,我和猪应该是同类,因为我们都是动物,他可以认为“人”和“猪”都实现了IAnimal这个接口,而他在研究动物行为时,不会把我和猪分开对待,而会从“动物”这个较大的粒度上研究,但他会认为我和一棵树有本质区别。

现在换了一个遗传学家,情况又不同了,因为生物都能遗传,所以在他眼里,我不仅和猪没区别,和一只蚊子、一个细菌、一颗树、一个蘑菇乃至一个SARS病毒都没什么区别,因为他会认为我们都实现了IDescendable这个接口(注:descend vi. 遗传),即我们都是可遗传的东西,他不会分别研究我们,而会将所有生物作为同类进行研究,在他眼里没有人和病毒之分,只有可遗传的物质和不可遗传的物质。但至少,我和一块石头还是有区别的。

 

也许你会觉得我上面的例子像在瞎掰,但是,这正是接口得以存在的意义。面向对象思想和核心之一叫做多态性,什么叫多态性?说白了就是在某个粒度视图层面上对同类事物不加区别的对待而统一处理。而之所以敢这样做,就是因为有接口的存在。像那个遗传学家,他明白所有生物都实现了IDescendable接口,那只要是生物,一定有Descend()这个方法,于是他就可以统一研究,而不至于分别研究每一种生物而最终累死。

可能这里还不能给你一个关于接口本质和作用的直观印象。那么在后文的例子和对几个设计模式的解析中,你将会更直观体验到接口的内涵。

3.面向接口编程综述

通过上文,我想大家对接口和接口的思想内涵有了一个了解,那么什么是面向接口编程呢?我个人的定义是:在系统分析和架构中,分清层次和依赖关系,每个层次不是直接向其上层提供服务(即不是直接实例化在上层中),而是通过定义一组接口,仅向上层暴露其接口功能,上层对于下层仅仅是接口依赖,而不依赖具体类

这样做的好处是显而易见的,首先对系统灵活性大有好处。当下层需要改变时,只要接口及接口功能不变,则上层不用做任何修改。甚至可以在不改动上层代码时将下层整个替换掉,就像我们将一个WD的60G硬盘换成一个希捷的160G的硬盘,计算机其他地方不用做任何改动,而是把原硬盘拔下来、新硬盘插上就行了,因为计算机其他部分不依赖具体硬盘,而只依赖一个IDE接口,只要硬盘实现了这个接口,就可以替换上去。从这里看,程序中的接口和现实中的接口极为相似,所以我一直认为,接口(interface)这个词用的真是神似!

使用接口的另一个好处就是不同部件或层次的开发人员可以并行开工,就像造硬盘的不用等造CPU的,也不用等造显示器的,只要接口一致,设计合理,完全可以并行进行开发,从而提高效率。

本篇文章先到这里。最后我想再啰嗦一句:面向对象的精髓是模拟现实,这也可以说是我这篇文章的灵魂。所以,多从现实中思考面向对象的东西,对提高系统分析设计能力大有脾益。

下篇文章,我将用一个实例来展示接口编程的基本方法。

而第三篇,我将解析经典设计模式中的一些面向接口编程思想,并解析一下.NET分层架构中的面向接口思想。

对本文的补充:

仔细看了各位的回复,非常高兴能和大家一起讨论技术问题。感谢给出肯定的朋友,也要感谢提出意见和质疑的朋友,这促使我更深入思考一些东西,希望能借此进步。在这里我想补充一些东西,以讨论一些回复中比较集中的问题。

 1.关于“面向接口编程”中的“接口”与具体面向对象语言中“接口”两个词

看到有朋友提出“面向接口编程”中的“接口”二字应该比单纯编程语言中的interface范围更大。我经过思考,觉得很有道理。这里我写的确实不太合理。我想,面向对象语言中的“接口”是指具体的一种代码结构,例如C#中用interface关键字定义的接口。而“面向接口编程”中的“接口”可以说是一种从软件架构的角度、从一个更抽象的层面上指那种用于隐藏具体底层类和实现多态性的结构部件。从这个意义上说,如果定义一个抽象类,并且目的是为了实现多态,那么我认为把这个抽象类也称为“接口”是合理的。但是用抽象类实现多态合理不合理?在下面第二条讨论。

概括来说,我觉得两个“接口”的概念既相互区别又相互联系。面向接口编程”中的接口是一种思想层面的用于实现多态性、提高软件灵活性和可维护性的架构部件,而具体语言中的“接口”是将这种思想中的部件具体实施到代码里的手段。

 2.关于抽象类与接口

看到回复中这是讨论的比较激烈的一个问题。很抱歉我考虑不周没有在文章中讨论这个问题。我个人对这个问题的理解如下:

如果单从具体代码来看,对这两个概念很容易模糊,甚至觉得接口就是多余的,因为单从具体功能来看,除多重继承外(C#,Java中),抽象类似乎完全能取代接口。但是,难道接口的存在是为了实现多重继承?当然不是。我认为,抽象类和接口的区别在于使用动机。使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。所以,如果你在为某个地方该使用接口还是抽象类而犹豫不决时,那么可以想想你的动机是什么。

看到有朋友对IPerson这个接口的质疑,我个人的理解是,IPerson这个接口该不该定义,关键看具体应用中是怎么个情况。如果我们的项目中有Women和Man,都继承Person,而且Women和Man绝大多数方法都相同,只有一个方法DoSomethingInWC()不同(例子比较粗俗,各位见谅),那么当然定义一个AbstractPerson抽象类比较合理,因为它可以把其他所有方法都包含进去,子类只定义DoSomethingInWC(),大大减少了重复代码量。

但是,如果我们程序中的Women和Man两个类基本没有共同代码,而且有一个PersonHandle类需要实例化他们,并且不希望知道他们是男是女,而只需把他们当作人看待,并实现多态,那么定义成接口就有必要了。

总而言之,接口与抽象类的区别主要在于使用的动机,而不在于其本身。而一个东西该定义成抽象类还是接口,要根据具体环境的上下文决定。

再者,我认为接口和抽象类的另一个区别在于,抽象类和它的子类之间应该是一般和特殊的关系,而接口仅仅是它的子类应该实现的一组规则。(当然,有时也可能存在一般与特殊的关系,但我们使用接口的目的不在这里)如,交通工具定义成抽象类,汽车、飞机、轮船定义成子类,是可以接受的,因为汽车、飞机、轮船都是一种特殊的交通工具。再譬如Icomparable接口,它只是说,实现这个接口的类必须要可以进行比较,这是一条规则。如果Car这个类实现了Icomparable,只是说,我们的Car中有一个方法可以对两个Car的实例进行比较,可能是比哪辆车更贵,也可能比哪辆车更大,这都无所谓,但我们不能说“汽车是一种特殊的可以比较”,这在文法上都不通。

 

我认为,抽象类和接口的区别在于使用动机。使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性 
-------------------------------------------------------------- 
不太认同,说抽象类相比接口有利于代码复用是正确的,但说接口的目的是实现多态,至少在多态的层面上,接口与抽象类都有体现,抽象类的virual方法难道就不是多态么?所以说接口是多态,抽象类也是多态。从设计目的上来说,接口和抽象类,本身就具有者非常类似的目的。那就是都是想制定一套规则,将具体问题进行抽象,归纳。但接口与抽象类还是有一定区别: 
1)二者不在一个层级 
 抽象类可以实现接口,但接口却无法继承抽象类吧?所以严格来说,接口是抽 象类的上级。 
2)作用域不同 
接口体现了的是相同类别或者不同类别下事物的归纳,而抽象类则更多的体现在对相同类别事务的归纳上。这在编程中的体现就是一个类可以实现多个接口,而不能继承多个抽象类,因为一个人能有各种的功能,这些功能可能是人类特有的,也可能是和其他动物共有的,但绝对不能有一个以上的亲生父亲。 
3)开放性有所不同 
 接口和抽象类虽然相似,但在某些场合,如分布式开发中,接口就更受欢迎,特别是面向服务中,更关注的是能干什么?而相比之下,是什么不太重要。是骡子,是马,是头驴,反正能拉车就可以。所以我认为接口相比抽象类更开放一点,更适合互操作一点。 

 

分享到:
评论

相关推荐

    面向接口编程详解——思想基础

    面向接口编程是一种编程范式,它是面向对象编程(OOP)的一个重要组成部分,而非独立的编程思想。在面向接口编程中,我们关注的是定义清晰、明确的行为规范,而不是具体的实现细节。接口作为一种契约,规定了类必须...

    面向接口编程详解(一)——思想基础.doc

    面向接口编程是面向对象编程中的一个重要概念,它并非与面向对象编程平级,而是面向对象思想的精华之一。本文将详细解释面向接口编程的思想基础。 首先,我们需要理解接口的定义和本质。接口在编程中是一个包含一...

    面向接口编程详解(二)——编程实例.doc

    面向接口编程详解(二)——编程实例 面向接口编程是一种编程思想,强调通过接口来实现多态性和可扩展性。在本文中,我们将通过一个实例来详细解释面向接口编程的思想和优点。 问题提出:我们要开发一个应用,模拟...

    面向接口编程详解(三)——模式研究.doc

    面向接口编程是一种重要的软件设计原则,它强调程序的组件应通过接口进行交互,而不是直接依赖于具体的实现。在本文档的第三部分,作者探讨了如何在实际的模式中运用这一原则,通过分析MVC(Model-View-Controller)...

    面向接口编程

    ### 面向接口编程详解 #### 一、面向接口编程与面向对象编程的关系 面向接口编程并非一种独立于面向对象编程之外的新编程思想,而是面向对象编程思想体系中的一个重要组成部分。面向对象编程的核心在于模拟现实...

    WCF入门详解————

    Windows Communication Foundation(WCF)是由Microsoft推出的一款面向服务的分布式通信编程框架。它是.NET Framework 3.5的重要组成部分,旨在简化跨平台、安全、可靠的分布式应用的开发过程。WCF不仅整合了.NET...

    Java基础入门编程详解

    Java基础入门编程详解,这本...综上所述,"打通经脉——Java基础入门编程详解"这个资源涵盖了Java编程的基础知识,适合初学者逐步掌握这门强大的编程语言。通过深入学习和实践,可以为进阶的Java开发打下坚实的基础。

    Windows API 开发详解——函数、接口、编程实例

    Windows API(Application Programming Interface)是微软为开发者提供的一组接口,用于编写能在Windows操作系统上运行的应用程序。这个API集成了大量的函数、结构体、枚举类型等,为开发者提供了丰富的功能,包括...

    MFC基础类库详解——中文msdn

    MFC(Microsoft Foundation Classes)是微软公司开发的一套C++类库,它基于面向对象编程思想,为Windows应用程序开发提供了一整套框架。MFC库是建立在Windows API之上的,它将复杂的Win32 API封装成易于使用的C++类...

    《圣殿祭司的ASP.NET 2.0开发详解——使用C#》光盘

    《圣殿祭司的ASP.NET 2.0开发详解——使用C#》是一部专注于ASP.NET 2.0技术的深入教程,特别强调了使用C#编程语言进行开发的方法。这本书籍光盘包含了丰富的资源,旨在帮助开发者全面掌握ASP.NET 2.0框架,提升Web...

    面向对象oop详解

    面向对象编程(OOP)是计算机编程中一种极为重要的范式,它的核心思想是将数据(属性)和行为(方法)封装成一个单独的实体——类。通过类的实例化,我们能够创建对象,并利用对象之间相互作用来解决实际问题。OOP的...

    Java编程语言入门 Java语言基础教程 第05课 oop1 Java的面向对象编程-继承、接口、包 共48页.pdf

    ### Java的面向对象编程——继承、接口、包 #### 一、面向对象编程基础 **1.1 类与对象** 面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它将数据和对数据的操作封装在一个实体内,即类...

    TCP/IP详解卷二——实现01

    《TCP/IP详解卷二——实现01》是深入理解TCP/IP协议栈实现的重要参考资料,它主要探讨了网络协议在操作系统中的...对于网络工程师、系统管理员和软件开发者而言,《TCP/IP详解卷二——实现》是一本不可多得的经典教程。

    Think in c++编程详解

    《Think in C++编程详解》是一本旨在帮助读者从初级水平逐步提升至高阶的C++编程指南。这本书深入浅出地介绍了C++语言的核心概念和技术,结合作者多年的编程实践经验,为学习者提供了丰富的知识与实用技巧。 首先,...

    圣殿祭司的ASP.NET2.0开发详解——使用C#

    "圣殿祭司的ASP.NET2.0开发详解——使用C#"可能是由一位名为"圣殿祭司"的作者编写的关于ASP.NET 2.0开发的教程或指南,专门针对C#编程语言。在2006年11月19日的最终版光盘中,可能包含了该教程的所有章节、源代码、...

    TCP/IP详解卷二——实现03

    《TCP/IP详解卷二——实现》是网络通信领域的一部权威著作,主要深入探讨了TCP/IP协议栈的实现原理和细节。本部分为该书的第三篇章,虽然具体章节未在列表中详细给出,但我们可以从一般的内容结构来推测可能涉及的...

Global site tag (gtag.js) - Google Analytics