`
Mybeautiful
  • 浏览: 298054 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

论接口与抽象类的真正区别

阅读更多

     关于接口与抽象类的区别, 有着千篇一律的答案,我就不重复那些了, 什么可以实现多个接口,但只能继承一个类;抽象类中可以有方法是的实现,而接口没有, 等等......

 

     那都没有说错,但没有说的问题的关键. 为什么接口跟抽象类有那些不同, 这些不同的根源是什么? 根源是它们的真正含义,或说作用是截然不同的. 不同在哪里? 一言以辟之, "抽象类是为了把相同的东西提取出来, 就是为了重用; 而接口的作用程序里面固化的契约, 是为了降低偶合." 下面进行详细阐述.

 

     先说抽象类, 它的作用归根到底其实就是为了重用. 这个重用包含几个层次的重用, 都知道的方法重用, 几个类有共同的特质, 我们就把他们公用的东西提取出来, 搞了个父类, 而这个父类有些方法不知道怎么实现, 就搞成抽象的吧. 所以抽象类就诞生了. 还有一个重用层次是结构的层次, 很典型的就是 Template模式, 它重用的不是一般的方法,而是做某类事情的通用算法,我称之为结构的重用.

 

     再谈接口, 这是我想重点说的, 因为我想让接口真正回归它本来的面目. 接口就是契约, 软件系统内部的契约. 那电脑硬件打比方, 内存条的卡口就规定好多长,卡位在哪. 这样造主板的按这个契约留好口, 造内存的外形也按这个造, 都造好了, 才能工作. 任何一方不守规矩,直接导致造电脑失败. 这个造电脑, 主板跟内存接口是什么? 是我们看到的主板上那个卡口吗? 不是, 接口是内存厂商跟主板厂商之间的契约, 这份契约可能是一份双方签字的文档,也可能是一个电话达成的共识.  而编程语言的接口Interface, 就对应那分签字的文档或是一个电话的共识, 只是它是程序化了的, 相关双方都没有办法违约的;我告诉你了我要这个接口, 你也答应实现, 那你就必须实现, 否则编译就过不了; 所以它是一种固化的强制的契约.

 

   搞清楚了接口跟抽象类的这个本质区别, 它们真正的作用. 就不会再说"这个地方, 用抽象类还是接口都可以"这样的话. 也许的确是都可以,但是该用哪个呢?

 

 

     ----------------

     本贴在论坛隐藏,但大虾们并没有说出像样的不同意见. 在此补充一下,

      当一个类实现一个接口,就是对所有其他说,我现在可以做这个事情了! 就是完成了interface规定的契约 或说协议。 而一个类实现另一个类时,并没有这个功能,它最多只是做了些同父类不一样的事情而已。

----------------------------------------------------------------------

张瑜,Mybeautiful, zhangyu0182@sina.com.

分享到:
评论
20 楼 飞雪无情 2010-03-31  
抽象类用来表示某一类物质,而接口则是一套共性的行为规范。如猫和狗都是动物(抽象类),而猫和狗都会走路,所以走路这个行为就可以定义到一个接口里面。
19 楼 prowl 2010-03-31  
单继承,抽象类要谨慎,接口优于抽象类。
18 楼 Mybeautiful 2010-03-31  
池中物 写道
关于抽象类观点基本比较统一,就是抽象某类物质的共性。

接口可以表示“契约”,但不就是契约,

还可以表示其它的,简单说 鸟类继承了 动物(抽象) 又实现了 Flyable,flyable也是契约吗?


“flyable也是契约吗?”是,你说你flyable,就一定要flyable,对使用该flyable接口的类/接口承诺了fly的能力, 这就是契约啊。
17 楼 池中物 2010-03-31  
关于抽象类观点基本比较统一,就是抽象某类物质的共性。

接口可以表示“契约”,但不就是契约,

还可以表示其它的,简单说 鸟类继承了 动物(抽象) 又实现了 Flyable,flyable也是契约吗?
16 楼 gdpglc 2010-03-31  
Mybeautiful 写道
gdpglc 写道
接口-> 抽象类-> 一般类,反应了现实事界中从一般到特殊的关系。
要对现实世界的问题进行处理,必须进行分解。抽象是一种高超的分解方法,通过对问题进行分析、归纳、形成高层的抽象认识,把问题分解成从一般到特殊的若干层次。在java中的接口、抽象类、一般类 是为了实现这种分解办法而提供的语言要素。


抽象的目的是什么? 把一般和特殊分开。 为什么要把一般和特殊分开? 是为了重用 一般。

抽象的目的是为了解决问题。在需求分析中,也是要进行抽象的,而在做需求时,无所谓重不重用。
正是因为OOA中的分析方法,可以在软件中得到表达,才能实现OOA到OOD在理论上的无逢过渡。

你说的重用,只是一种编程技巧吧?
15 楼 Mybeautiful 2010-03-31  
gdpglc 写道
接口-> 抽象类-> 一般类,反应了现实事界中从一般到特殊的关系。
要对现实世界的问题进行处理,必须进行分解。抽象是一种高超的分解方法,通过对问题进行分析、归纳、形成高层的抽象认识,把问题分解成从一般到特殊的若干层次。在java中的接口、抽象类、一般类 是为了实现这种分解办法而提供的语言要素。


抽象的目的是什么? 把一般和特殊分开。 为什么要把一般和特殊分开? 是为了重用 一般。
14 楼 hyj1254 2010-03-31  
接口就像一个个插件,互相独立,使用者可以根据需求任意决定用谁、不用谁、用几个。
13 楼 gdpglc 2010-03-31  
接口-> 抽象类-> 一般类,反应了现实事界中从一般到特殊的关系。
要对现实世界的问题进行处理,必须进行分解。抽象是一种高超的分解方法,通过对问题进行分析、归纳、形成高层的抽象认识,把问题分解成从一般到特殊的若干层次。在java中的接口、抽象类、一般类 是为了实现这种分解办法而提供的语言要素。
12 楼 Mybeautiful 2010-03-31  
godfish 写道
这应该是一个软件设计的问题,一般上业务接口都是针对interface来设计, Abstract是对接口公共部分的封装。

同意! Abstract是为了“公共部分”的封装,也就是重用;一般上业务接口都是针对interface来设计,为什么要针对接口设计呢? 就是为了解耦。
11 楼 qiren83 2010-03-31  
角度有点意思 很轻松的解答方式
10 楼 JE帐号 2010-03-31  
接口和抽象类是不同的概念,不适合放在一起比较.
9 楼 godfish 2010-03-31  
这应该是一个软件设计的问题,一般上业务接口都是针对interface来设计, Abstract是对接口公共部分的封装。
8 楼 tottichen 2010-03-31  
很多东西很难有统一的答案,只要自己知道为的是什么就可以了。毕竟有的东西只可意会,不可言传。
7 楼 Evin7 2010-03-31  
曾经一个领导问我这个问题,我给出了自己的想法,领导不赞同,领导的说法是:抽象类可以继承,接口不行。没理解,接口就是接口,抽象类就是抽象类,本来就是不同的东西,为什么非要拿来做比较。
6 楼 wjjxf 2010-03-31  
经验之谈,写的不错
5 楼 sdnasky 2010-03-31  
公有方法就是接口
4 楼 rongzhi_li 2010-03-31  
接口 本来就是一个含糊不清 有争议的翻译
所以怎么答都有理
3 楼 luffyke 2010-03-31  
http://topic.csdn.net/u/20100312/10/822b0e94-8d2f-4bf0-9746-3424eaea40ce.html
这是我在CSDN上的帖子,讨论了接口和内部类的区别
2 楼 Mybeautiful 2010-03-31  
wumingshi 写道
回答问题的角度不同。从语法与语言的角度说,就是“实现,继承..."的区别。在C++中根本就没有interface这个东西,需要用纯虚函数和宏模拟。如果是从设计的角度,就不应该提这个问题。它的使用场景应该是设计师对他们的最根本理解。

另外,interface却常常与抽象类在一起使用。定义了interface,经常需要用一个抽象类来吧共同的行为实现,而留下具体的行为给继承类去实现。


1. "在C++中根本就没有interface这个东西,需要用纯虚函数和宏模拟", 那正好说明 C++中的Interface就是“纯虚函数和宏模拟”一起实现的 (本人不了解任何C++,从字面意思推测的);所以从逻辑语义来将,无论C++还是java都有抽象类跟接口的概念,当然就都有其不同的使用场景了。

2. "如果是从设计的角度,就不应该提这个问题", 用什么不用什么,恰恰就是一个设计问题,详细设计中是一定要写清楚的。

3. "interface却常常与抽象类在一起使用。定义了interface,经常需要用一个抽象类来吧共同的行为实现", 恕不敢苟同, 就像男人跟女人一样,他们可以结婚一起生活,也可以选择单身,或是Gay都是完全允许的。 需不需要一起使用, 就如同wumingshi所说,要看场景,并非他们天然就需要一起用,或是一起用更好。
1 楼 wumingshi 2010-03-30  
回答问题的角度不同。从语法与语言的角度说,就是“实现,继承..."的区别。在C++中根本就没有interface这个东西,需要用纯虚函数和宏模拟。如果是从设计的角度,就不应该提这个问题。它的使用场景应该是设计师对他们的最根本理解。

另外,interface却常常与抽象类在一起使用。定义了interface,经常需要用一个抽象类来吧共同的行为实现,而留下具体的行为给继承类去实现。

相关推荐

    Solid经典论文11篇

    这通常通过抽象接口或抽象类实现,允许增加新的实现而不影响已有的代码。 3. **里氏替换原则(LSP)**:里氏替换原则规定,子类型必须能够替换掉它们的基类型,并且在程序中不会产生任何不正确的行为。这意味着子类...

    关于DAO的相关论文

    DAO,全称为“数据访问对象”(Data Access Object),是软件设计模式中的一种,主要用于数据库操作的抽象。在本文中,我们将深入探讨DAO的概念、作用、实现方式以及它在实际开发中的应用。 DAO模式的核心思想是将...

    高级软件工程师面试题

    接口的使用与区别 接口定义了一组行为规范,任何实现了该接口的类必须提供这些行为的具体实现。Java支持多重接口实现,这为设计灵活的模块化系统提供了可能。 ##### 4. 内部类与外部类的区别 内部类可以访问外部...

    《信息系统建模与uml》-4

    - **Abstract Class and Interface**:用于定义抽象类和接口。 - **Polymorphism**:通过方法重写实现多态性。 - **Package and Scope**:定义包和作用域。 以上就是从给定文件的标题、描述、标签以及部分内容中...

    OOD启思录-面向对象圣典(英文版)

    - **最小化类间依赖**(Heuristic #2.7):一个类只能使用另一个类公共接口中的操作,或者根本不与那个类有关联。这样可以减少类间的耦合度。 - **支持单一职责的类**(Heuristic #2.8):一个类应当捕捉唯一的关键...

    Linux PCI驱动牛人论文

    在Linux操作系统中,设备驱动程序扮演着核心角色,它们作为操作系统与硬件设备之间的桥梁,实现了硬件抽象层,使软件开发者无需关注底层硬件细节。Linux将硬件设备视为“设备文件”,并提供了一套标准化的系统调用来...

    面向对象设计的69条经验原则

    这条原则提醒开发者在设计时要区分对象的功能角色和实体角色,确保设计的类真正代表了系统中的实体。 ### 13: 在水平方向上尽可能统一地分布系统功能 这条原则鼓励开发者在设计时让不同的顶层类平均分担工作,避免...

    精通面向对象的分析和设计之秘诀

    4. **抽象**:抽象是简化复杂性的过程,通过定义接口或抽象类来概括共同特征,忽略不重要的细节。这有助于关注问题的关键部分,降低设计的复杂度。 5. **设计模式**:设计模式是解决常见设计问题的最佳实践,如单例...

    凑积分11111111111

    - **安全性**:确保只有真正支持的接口才能被使用,避免了不安全的接口访问。 - **可扩展性**:组件可以在后续版本中添加新的接口,而无需修改现有的 `QueryInterface` 实现。 #### 1.2 AddRef 和 Release 函数的...

    61条面向对象分析设计的经验原则.txt

    在软件开发过程中,面向对象的设计与分析是一种广泛采用的方法论。它强调通过抽象、封装、继承和多态等核心概念来构建系统。本文旨在对《61条面向对象分析设计的经验原则》中的关键点进行详细的解读与分析,帮助读者...

    C++世界最权威的观点

    他提到了多重继承、抽象类以及多范式编程等概念,并解释了“资源获取即初始化”(RAII)这一原则。RAII是一种强大的机制,用于确保资源(如内存分配、文件句柄等)的自动管理,从而减少了编程错误的可能性。 #### 五...

    24种设计模式介绍与6大设计原则

    抽象工厂模式提供一个接口,用于创建一系列相关的或相互依赖的对象,而无需指定它们具体的类。这是一种更为复杂的工厂方法模式,适用于创建复杂对象。 **7. 门面模式 (Facade Pattern)** 门面模式提供一个统一的...

    设计模式培训-strategy.pdf

    将飞行行为抽象为一个策略接口,然后创建多个实现该接口的具体策略类,如FlyWithWings、FlyNoWay等。这样,Duck类可以持有一个飞行策略对象,根据鸭子类型的不同,动态地设置不同的飞行策略,实现了真正的“策略替换...

    haskell中文教程

    类似于其他语言的接口或抽象类,Haskell 的类型类定义了一组操作符和函数,允许在不同类型的值之间共享行为。例如,`Eq` 类型类定义了等于和不等于的操作符。 7. **模块系统** Haskell 的模块系统支持代码组织和...

    代码生成器Mgicode生成器JAVA代码生成器

    软件是用来对世界进行描述的一种方式,最初我们采用过程的编程,后来与世界的描述不相符,所以就出现了面向对象,而现在面向对象并不能很好地解析如抽象类,Service类等。要解释这些东西,最好的方式是通过关系来...

    UML期末复习总结.docx

    2. **规格说明透视图**: 使用UML图来描述软件组件的抽象表示,包括规格说明和接口。 3. **实现透视图**: 使用UML图来描述具体技术下的软件实现细节。 **不同透视图中的“类”的含义:** - **概念类**: 指的是现实...

    设计模式英文版-Design Pattern Explained

    3. **抽象工厂模式**:提供一个接口用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。 4. **建造者模式**:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。 5. **原型模式*...

Global site tag (gtag.js) - Google Analytics