`
TonyLian
  • 浏览: 402100 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【第16条】接口优于抽象类

阅读更多

    Java语言提供了两种机制,可以用来定义一个允许多个实现的类型:接口抽象类。如果对它们的基本定义还不是很清楚请参考其它书籍。

 

    接口抽象类这二者比较起来,从特征来说,最明显的区别在于抽象类允许包含某些方法的实现,但是接口是不允许的。但是在使用方面还有一个更为突出的区别,就是抽象类是通过被子类继承来使用的;而接口是通过被实现来使用的。而Java是一种单继承机制的语言,所以就限制了抽象类的使用。(一个类只有一个超类或叫父类)当一个类已经继承了一个超类时,现在你再想因为一些原因让它再继承一个抽象类是不可能的(当然也有变通办法,就是先让这个抽象类继承那个超类,再把子类的超类改为这个抽象类。即原超类和子类的关系从父子关系变为了爷孙关系,中间插了这个抽象类)。这时候就能体现出接口的优势了——一个类可以实现多个接口(其实这也是Java之所以大胆地放弃多继承的原因)。

 

    再来罗列一下使用接口的其他好处吧:

1)已有的类可以很容易被更新,以实现新的接口。

     其实这就是上面说的,如果是使用抽象类就麻烦了。

 

2)接口是定义混合类型的理想选择。

 

3)接口使得我们可以构造出非层次结构的类型框架。

     层次结构用来描述组织机构这样的事物是非常合适的。但并不是所有事物都适用。

    

      举一个汽车的例子:

     【继承的思想】: 车 — 汽车 — 广义乘用车 — 轿车 — 小轿车 — 大众品牌小轿车 — 捷达车 — 捷达出租车

      这样的继承,直到“小轿车”之前还是合适的,从意义来说,这些类都应该是抽象类,因为无法实例化一个“小轿车”,它只是一类车的统称,只有某一辆,比如:京 B12345牌照号的(或者更严谨地用车架号)具体车才应该可以实例化。

      然而到了“大众品牌小轿车”之后就不合适了。显然,“大众品牌”不仅仅有“小轿车”,“捷达车”也不仅仅有“车租车”。这时候就该使用接口了。

 

public class MyCar extends 小轿车 implements 大众品牌, 捷达牌, 车租车able {

    public MyCar(String sn){
  .....
    }

}

 

4)接口使得安全地增强一个类的功能成为可能

     方法是使用包装类模式。我个人并不喜欢这样的做法,就不细说了。

 

   说了这么多接口的好处,那么抽象类是一无是处的吗?当然不是。一个明显的优势是,抽象类的演化(版本更新)比接口容易的多。如果在后续版本中你希望在抽象类中增加一个新方法,那么你直接增加就好了。你其实就是在抽象类中给出了一个默认的实现而已,子类会自然地继承这个方法,子类可以自由选择是否改写这个方法。

 

   接口就不行了。一旦发行你就不能在增加新的方法的定义了(还记得之前提到过几次的“你有义务保持向前兼容”吗?)。如果你增加了新的方法的定义,那么所有实现了此接口的类就统统要增加对此方法的实现,如果你的接口已经发布,那么这几乎是不可能的(除非只有你自己用你之前版本的发行包)。

 

   关于骨架实现类:在选择抽象类和接口时,并不是二选一的答案,或干脆枪毙掉抽象类。其实,你可以把接口和抽象类的优点结合起来,对于你希望导出(对外提供)的每一个重要接口都提供一个抽象类(骨架实现类)。接口的作用仍然是定义类型,骨架实现类负责所有与接口实现相关的工作。

 

   按照惯例,骨架实现类的命名方法为: AbstractInterface,这里的Interface指的是接口的名字。建议你也去读读AbstractList、AbstractMap的源码,或许有不少启发。(我也要去再读读...)

 

 

 

 

【Effective Java 学习笔记】系列连载专题请见:
http://tonylian.iteye.com/categories/64208

 

1
0
分享到:
评论
2 楼 TonyLian 2009-05-15  
liujunsong 写道

说实话,都不是啥好东西. 项目里面这种东西多了,将来就会象天书一样,没有人能看得懂. 因为用这东西象抽烟一样,来一根,那就来一根吧. 用起来很容易变得特随便,东一个接口,西一个接口,左一个抽象,右一个抽象. 当时还能说明白是干啥的,时间长了,没有人知道为啥这么设计了. 可是木已成舟,只能继续凑合下去了.


对于具体业务开发是应当控制这两者的“创造”。但是作为Framework来说,他们是必要的。接口的作用体现在解耦合,抽象类的作用体现在为实现提供默认方式。
1 楼 liujunsong 2009-05-14  
说实话,都不是啥好东西.
项目里面这种东西多了,将来就会象天书一样,没有人能看得懂.
因为用这东西象抽烟一样,来一根,那就来一根吧.
用起来很容易变得特随便,东一个接口,西一个接口,左一个抽象,右一个抽象.
当时还能说明白是干啥的,时间长了,没有人知道为啥这么设计了.
可是木已成舟,只能继续凑合下去了.

相关推荐

    面向对象程序设计的原则

    14. **接口优于实现**:规划一个清晰的接口而非急于实现,有助于后期的扩展和重构。 15. **关注数据集中性**:类应确保相关数据和行为的集中,避免大量访问方法的存在,这表明数据和行为可能分散。 16. **模型-...

    61条Java面向对象设计的经验原则.

    #### 原则十四:接口优于实现 - **原则**:规划一个接口而不是实现一个接口。 - **解释**:在设计阶段,应该先定义好接口,再考虑其实现细节。这样可以确保接口的合理性,并提高系统的扩展性。 #### 原则十五:警惕...

    软件框架设计的艺术

    第16章 团队协作 286 16.1 在提交代码时进行代码评审 286 16.2 说服开发人员为他们的API提供文档 290 16.3 尽职尽责的监控者 292 16.4 接受API的补丁 297 第17章 利用竞赛游戏来提升API设计技巧 ...

    java面试宝典

    **知识点1:接口-抽象类-类区别** - **接口**: 接口是一种特殊类型的类,它只能包含抽象方法和常量。Java中一个类可以实现多个接口,用于定义一组行为规范。 - **抽象类**: 抽象类是一种不能被实例化的类,它可以...

    【试题】JAVA面试之经典题库

    接口可以继承其他接口,抽象类可以实现接口,但抽象类不能继承具体类(concrete class)。 #### 二十三、启动线程 应使用`start()`方法启动线程,这会调用线程的`run()`方法。直接调用`run()`方法不会创建新线程。...

    判断选择笔试文件.pdf

    - **抽象类**:含有至少一个抽象方法的类被称为抽象类。抽象类本身不能被实例化,只能作为其他类的基类。 #### 11. Java 应用程序运行环境 - **Java虚拟机(JVM)**:Java程序运行在Java虚拟机上,JVM负责执行Java...

    Java代码编写30条建议

    - 优先使用接口而非抽象类进行面向接口的编程。 - 接口提供了更好的灵活性和扩展性,使得代码更加松耦合。 - 当需要具体实现时,可以考虑使用抽象类来提供部分默认实现。 #### 14. 代码的可维护性 - 保持代码结构...

    Java入门学习笔记

    - 抽象类包含抽象方法,抽象方法是没有实现的方法,子类必须实现所有抽象方法才能被实例化。 **7.8 接口(模板方法模式)** - 接口定义了一组方法,但不提供实现,实现接口的类必须提供所有方法的实现。 - 模板方法...

    java最经典面试题.doc

    #### 八、抽象类与接口之间的区别 - **抽象类**: - 可以包含构造器、抽象方法、具体方法、字段等。 - 不允许实例化,但可以声明指向抽象类类型的引用变量。 - 只能被一个类继承。 - **接口**: - 不能包含构造...

    UML和模式应用(架构师必备).part01.rar

    16.10 泛化、抽象类、抽象操作 16.11 依赖 16.12 接口 16.13 组合优于聚合 16.14 约束 16.15 限定关联 16.16 关联类 16.17 单实例类 16.18 模板类和接口 16.19 用户自定义的分栏 16.20 主动类 16.21 交互...

    UML和模式应用(架构师必备).part07.rar

    16.10 泛化、抽象类、抽象操作 16.11 依赖 16.12 接口 16.13 组合优于聚合 16.14 约束 16.15 限定关联 16.16 关联类 16.17 单实例类 16.18 模板类和接口 16.19 用户自定义的分栏 16.20 主动类 16.21 交互...

    UML和模式应用(架构师必备).part02.rar

    16.10 泛化、抽象类、抽象操作 16.11 依赖 16.12 接口 16.13 组合优于聚合 16.14 约束 16.15 限定关联 16.16 关联类 16.17 单实例类 16.18 模板类和接口 16.19 用户自定义的分栏 16.20 主动类 16.21 交互...

    UML和模式应用(架构师必备).part06.rar

    16.10 泛化、抽象类、抽象操作 16.11 依赖 16.12 接口 16.13 组合优于聚合 16.14 约束 16.15 限定关联 16.16 关联类 16.17 单实例类 16.18 模板类和接口 16.19 用户自定义的分栏 16.20 主动类 16.21 交互...

    UML和模式应用(架构师必备).part03.rar

    16.10 泛化、抽象类、抽象操作 16.11 依赖 16.12 接口 16.13 组合优于聚合 16.14 约束 16.15 限定关联 16.16 关联类 16.17 单实例类 16.18 模板类和接口 16.19 用户自定义的分栏 16.20 主动类 16.21 交互...

    UML和模式应用(架构师必备).part04.rar

    16.10 泛化、抽象类、抽象操作 16.11 依赖 16.12 接口 16.13 组合优于聚合 16.14 约束 16.15 限定关联 16.16 关联类 16.17 单实例类 16.18 模板类和接口 16.19 用户自定义的分栏 16.20 主动类 16.21 交互...

    UML和模式应用(架构师必备).part05.rar

    16.10 泛化、抽象类、抽象操作 16.11 依赖 16.12 接口 16.13 组合优于聚合 16.14 约束 16.15 限定关联 16.16 关联类 16.17 单实例类 16.18 模板类和接口 16.19 用户自定义的分栏 16.20 主动类 16.21 交互...

    UML和模式应用(架构师必备).part08.rar

    16.10 泛化、抽象类、抽象操作 16.11 依赖 16.12 接口 16.13 组合优于聚合 16.14 约束 16.15 限定关联 16.16 关联类 16.17 单实例类 16.18 模板类和接口 16.19 用户自定义的分栏 16.20 主动类 16.21 交互...

    Java选择题.pdf

    多态主要通过方法的覆盖(overriding)和抽象类或接口实现。 多态性是面向对象编程的核心概念之一,表示具有相同接口的不同对象可以以适合各自方式处理同一件事情。选项C正确地描述了这一点。A选项描述的是类的继承...

    2021-2022计算机二级等级考试试题及答案No.16903.docx

    3. 当一个类实现接口时,它必须实现接口中定义的所有方法,否则该类应被声明为抽象类,因为抽象类可以包含未实现的方法。 4. Access2000的数据库文件扩展名为.MDB,其中包含了数据库的所有对象,如表、查询、窗体、...

Global site tag (gtag.js) - Google Analytics