`
edicky
  • 浏览: 38557 次
  • 来自: ...
社区版块
存档分类
最新评论

JAVA面向接口编程详解

阅读更多

  在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的对系统设计人员来讲就不那么重要 了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主 要工作内容。面向接口编程我想就是指按照这种思想来编程吧!实际上,在日常工作中,你已经按照接口编程了,只不过如果你没有这方面的意识,那么你只是在被 动的实现这一思想;表现在频繁的抱怨别人改的代码影响了你(接口没有设计到),表现在某个模块的改动引起其他模块的大规模调整(模块接口没有很好的设计) 等等。

  Booch先生那天谈到Interaction Designer,它就是指做这类设计的人,只不过层次更高一些。我想目前我们的软件设计队伍中,这类人是最缺乏的人才之一。
非接口编程?是不是就是面向过程的编程思想?

  1.关于接口的理解。
  接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
  我们在一般实现一个系统的时候,通常是将定义与实现合为一体,不加分离的,我认为最为理解的系统设计规范应是所有的定义与实现分离,尽管这可能对系统中的某些情况有点繁烦。
  接口的本身反映了系统设计人员对系统的抽象理解。
  接口应有两类:第一类是对一个体的抽象,它可对应为一个抽象体(abstract class);
  第二类是对一个体某一方面的抽象,即形成一个抽象面(interface);
  一个体有可能有多个抽象面。
  抽象体与抽象面是有区别的。

  2.设计接口的另一个不可忽视的因素是接口所处的环境(context,environment),系统论的观点:环境是系统要素所处的空间 与外部影响因素的总和。任何接口都是在一定的环境中产生的。因此环境的定义及环境的变化对接口的影响是不容忽视的,脱离原先的环境,所有的接口将失去原有 的意义。

  3.按照组件的开发模型(3C),它们三者相辅相成,各司一面,浑然一体,缺一不可。

  面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法
  面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现
  接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题

  我认为:UML里面所说的interface是协议的另一种说法。并不是指com的interface,CORBA的interface,Java的interface,Delphi的interface,人机界面的interface或NIC的interface。

  在具体实现中,是可以把UML的interface实现为语言的interface,分布式对象环境的interface或其它什么 interface,但就理解UML的interface而言,指的是系统每部分的实现和实现之间,通过interface所确定的协议来共同工作。

  所以我认为,面向interface编程,原意是指面向抽象协议编程,实现者在实现时要严格按协议来办。也就是BillJoy同志说的,一边 翻rfc,一边写代码的意思。面向对象编程是指面向抽象和具象。抽象和具象是矛盾的统一体,不可能只有抽象没有具象。一般懂得抽象的人都明白这个道理。 但有的人只知具象却不知抽象为何物。

  所以只有interface没有实现,或只有实现而没有interface者是没有用的,反OO的。

  所以还是老老实实面向对象编程,面向协议编程,或者什么都不面向,老老实实编程。

  但是我很讨厌讨论这样的术语,不如我们谈谈什么叫面向领导的编程?面向用户的编程?领导和用户有时都很BT,我们就面向BT编程?



选择Java接口还是抽象类

很多人有过这样的疑问:为什么有的地方必须使用接口而不是抽象类,而在另一些地方,又必须使用抽象类而不是接口呢?或者说,在考虑Java类的一般化问题时,很多人会在接口和抽象类之间犹豫不决,甚至随便选择一种。

  实际上接口和抽象类的选择不是随心所欲的。要理解接口和抽象类的选择原则,有两个概念很重要:对象的行为和对象的实现。如果一个实体可以有多 种实现方式,则在设计实体行为的描述方式时,应当达到这样一个目标:在使用实体的时候,无需详细了解实体行为的实现方式。也就是说,要把对象的行为和对象 的实现分离开来。既然Java的接口和抽象类都可以定义不提供具体实现的方法,在分离对象的行为和对象的实现时,到底应该使用接口还是使用抽象类呢?


通过抽象类建立行为模型


  在接口和抽象类的选择上,必须遵守这样一个原则:行为模型应该总是通过接口而不是抽象类定义。为了说明其原因,下面试着通过抽象类建立行为模型,看看会出现什么问题。

  假设要为销售部门设计一个软件,这个软件包含一个“发动机”(Motor)实体。显然无法在发动机对象中详细地描述发动机的方方面面,只能描述某些对当前软件来说重要的特征。至于发动机的哪些特征是重要的,则要与用户(销售部门)交流才能确定。

  销售部门的人要求每一个发动机都有一个称为马力的参数。对于他们来说,这是惟一值得关心的参数。基于这一判断,可以把发动机的行为定义为以下行为。

  行为1:查询发动机的马力,发动机将返回一个表示马力的整数。

  虽然现在还不清楚发动机如何取得马力这个参数,但可以肯定发动机一定支持这个行为,而且这是所有发动机惟一值得关注的行为特征。这个行为特征 既可以用接口定义,也可以用抽象类定义。为了说明用抽象类定义可能出现的问题,下面用抽象类建立发动机的行为模型,并用Java方法描述行为1,代码如 下:

Java代码  收藏代码
  1. public   abstract  Motor{              
  2.          abstract   public   int  getHorsepower();              
  3.       }  
  4.    



  在Motor抽象类的基础上构造出多种具体实现,例如A型发动机、B型发动机等,再加上系统的其它部分,最后得到1.0版的软件并交付使用。 一段时间过去了,现在要设计2.0版的软件。在评估2.0版软件需求的过程中,发现一小部分发动机是电池驱动的,而电池需要一定的充电时间。销售部门的人 希望能够通过计算机查阅充电时间。根据这一要求定义一个新的行为,如图1所示。

  行为2:查询电驱动发动机的充电时间,发动机将返回一个表示充电时间的整数。

  用Java方法来描述这个行为,代码如下:

Java代码  收藏代码
  1. public   abstract  BatteryPoweredMotor  extends  Motor{             
  2.         abstract   public   int  getTimeToRecharge();            
  3.       }  
  4.    



  在销售部门的软件中,电驱动发动机也以类的形式实现,但这些类从BatteryPoweredMotor而不是Motor派生。这些改动加入 到2.0版软件之后,销售部门很满意。随着业务的不断发展,不久之后光驱动的发动机出现了。销售部门要求光驱动发动机需要一定光能才能运转,光能以流明 (Lumen)度量。这个信息对客户很重要,因为下雨或多云的天气里,某些光驱动发动机可能无法运转。销售部门要求为软件增加对光驱动发动机的支持,所以 要定义一个新的行为。

  行为3:查询光驱动发动机能够正常运转所需要的最小流明数,发动机返回一个整数。

  再定义一个抽象类并把行为3转换成Java方法,代码如下:

Java代码  收藏代码
  1. public   abstract  SolarPoweredMotor  extends  Motor{              
  2.          abstract   public   int  getLumensToOperate();            
  3.       }  






  如图1所示,SolarPoweredMotor和BatteryPoweredMotor都从Motor抽象类派生。在整个软件中,90% 以上的代码以相同的方式对待所有的发动机。偶尔需要检查一下发动机是光驱动还是电驱动,使用instanceof实现,代码如下:

Java代码  收藏代码
  1. if  ( instanceof  SolarPoweredMotor){...}         
  2.          if  ( instanceof  BatteryPoweredMotor){...}  




  无论是哪种发动机,马力这个参数都很重要,所以在所有派生的抽象类(SolarPoweredMotor和BatteryPoweredMotor)中,getHorsepower()方法都有效。

  现在销售部门又有了一种新的发动机,它是一种既有电驱动又有光驱动的双重驱动发动机。光驱动和电驱动的行为本身没有变化,但新的发动机同时支 持两种行为。在考虑如何定义新型的光电驱动发动机时,接口和抽象类的差别开始显示出来了。新的目标是在增加新型发动机的前提下尽量少改动代码。因为与光驱 动发动机、电驱动发动机有关的代码已经过全面的测试,不存在已知的Bug。为了增加光电驱动发动机,要定义一个新的 SolarBatteryPowered抽象类。如果让SolarBatteryPowered从Motor抽象类派 生,SolarBatteryPowered将不支持针对光驱动发动机和电驱动发动机的instanceof操作。也就是说,如果查询一个光电驱动的发动 机是光驱动的,还是电驱动的,得到的答案是:都不是。

  如果让SolarBatteryPowered从SolarPoweredMotor(或BatteryPoweredMotor)抽象类派 生,类似的问题也会出现,SolarBatteryPowered将不支持针对BatteryPoweredMotor(或 SolarPoweredMotor)的instanceof操作。从行为上看,光电驱动的发动机必须同时从两个抽象类派生,但Java语言不允许多重继 承。之所以会出现这个问题,根本的原因在于使用抽象类不仅意味着定义特定的行为,而且意味着定义实现的模式。也就是说,应该定义一个发动机如何获得行为的 模型,而不仅仅是声明发动机具有某一个行为。


通过接口建立行为模型


  如果用接口来建立行为模型,就可以避免隐含地规定实现模式。例如,前面的几个行为改用接口定义如下。

  行为1:

Java代码  收藏代码
  1. public   interface  Motor(){            
  2.         public   int  getHorsepower();            
  3.       }  
  4.    



行为2:

Java代码  收藏代码
  1. public   interface  BatteryPoweredMotor  extends  Motor(){             
  2.   public   int  getTimeToRecharge();            
  3. }  




行为3:

Java代码  收藏代码
  1. public   interface  SolarPoweredMotor  extends  Motor{             
  2.   abstract   public   int  getLumensToOperate();            
  3. }  




  现在光电驱动的发动机可以描述为:

Java代码  收藏代码
  1. public  DualPoweredMotor  implements  SolarPoweredMotor, BatteryPoweredMotor{}  






  DualPoweredMotor只继承行为定义,而不是行为的实现模式,如图2所示。

  在使用接口的同时仍旧可以使用抽象类,不过这时抽象类的作用是实现行为,而不是定义行为。只要实现行为的类遵从接口定义,即使它改变了父抽象 类,也不用改变其它代码与之交互的方式。特别是对于公用的实现代码,抽象类有它的优点。抽象类能够保证实现的层次关系,避免代码重复。然而,即使在使用抽 象类的场合,也不要忽视通过接口定义行为模型的原则。从实践的角度来看,如果依赖于抽象类来定义行为,往往导致过于复杂的继承关系,而通过接口定义行为能 够更有效地分离行为与实现,为代码的维护和修改带来方便。



Java接口特性学习
在Java中看到接口,第一个想到的可能就是C++中的多重继承和Java中的另外一个关键字abstract。从另外一个角度实现多重继承是接 口的功能之一,接口的存在可以使Java中的对象可以向上转型为多个基类型,并且和抽象类一样可以防止他人创建该类的对象,因为接口不允许创建对象。

interface关键字用来声明一个接口,它可以产生一个完全抽象的类,并且不提供任何具体实现。interface的特性整理如下:

1.        接口中的方法可以有参数列表和返回类型,但不能有任何方法体。

2.        接口中可以包含字段,但是会被隐式的声明为static和final。

3.        接口中的字段只是被存储在该接口的静态存储区域内,而不属于该接口。

4.        接口中的方法可以被声明为public或不声明,但结果都会按照public类型处理。

5.        当实现一个接口时,需要将被定义的方法声明为public类型的,否则为默认访问类型,Java编译器不允许这种情况。

6.        如果没有实现接口中所有方法,那么创建的仍然是一个接口。

7.        扩展一个接口来生成新的接口应使用关键字extends,实现一个接口使用implements。



interface在某些地方和abstract有相似的地方,但是采用哪种方式来声明类主要参照以下两点:

1.        如果要创建不带任何方法定义和成员变量的基类,那么就应该选择接口而不是抽象类。

2.        如果知道某个类应该是基类,那么第一个选择的应该是让它成为一个接口,只有在必须要有方法定义和成员变量的时候,才应该选择抽象类。因为抽象类中允许存在一个或多个被具体实现的方法,只要方法没有被全部实现该类就仍是抽象类。


以上就是接口的基本特性和应用的领域,但是接口绝不仅仅如此,在Java语法结构中,接口可以被嵌套,既可以被某个类嵌套,也可以被接口嵌套。这 在实际开发中可能应用的不多,但也是它的特性之一。需要注意的是,在实现某个接口时,并不需要实现嵌套在其内部的任何接口,而且,private接口不能 在定义它的类之外被实现。

分享到:
评论

相关推荐

    面向接口编程详解,chm文件

    面向接口编程详解.chm面向接口编程详解.chm面向接口编程详解.chm

    Java面向接口编程之命令模式实例详解

    主要介绍了Java面向接口编程之命令模式,结合实例形式详细分析了Java面向接口编程命令模式的定义、使用方法及相关操作注意事项,需要的朋友可以参考下

    Java网络socket编程详解

    Java网络socket编程详解 7.2 面向套接字编程 我们已经通过了解Socket的接口,知其所以然,下面我们就将通过具体的案例,来熟悉Socket的具体工作方式 7.2.1使用套接字实现基于TCP协议的服务器和客户机程序 依据...

    Java开发详解.zip

    031710_【第17章:Java数据库编程】_CallableStatement接口笔记.pdf 031711_【第17章:Java数据库编程】_JDBC 2.0操作笔记.pdf 031712_【第17章:Java数据库编程】_事务处理笔记.pdf 031713_【第17章:Java数据库...

    java基础面试题目详解

    Java 是一种面向对象开发的编程语言,它最厉害的是实现一处编译,处处运 行,可以摒弃底层操作系统的差异性。 JDK(Java Development Kit)是针对 Java 开发员的产品,是整个 Java 的 核心,包括了 Java 运行环境 ...

    Java 2精要:语言详解与编程指南

    Java以其简单、面向对象、分布式、解释性、强壮、安全、与系统无关、可移植、高性能、动态性和多线程的特点风靡全球,成为计算机网络编程的主流工具。Java 2提供的新的图形用户界面特性—Swing,填补了以前版本的...

    Java Bug模式详解

    Java.Bug模式详解 第1章 混乱环境下的灵活方法 1.1 软件设计、实现和维护的趋势 1.1.1 对于稳定、安全 系统的需求增加 1.1.2 传统软件工程技 术的局限性 1.1.3 开放源代码的软 件项目的可利用性 1.1.4 对于...

    java基础案例与开发详解案例源码全

    19.2 Java网络类和接口497 19.3 InetAddress类498 19.4 URL和URLConnection类499 19.5 Scoket套接字505 19.6 Datagram套接字509 19.7 综合示例512 19.8 本章习题520 第20章 20.1 网络版五子棋522 20.1.1 需求描述522...

    面向对象详解和JVM底层内存分析

    让我来解释一下面向对象编程的核心概念: 对象: 对象是面向对象编程的基本单元,它包含数据和操作数据的方法。在现实世界中,对象可以是任何可以观察和识别的事物,如人、车、动物等。在程序设计中,对象则是对...

    Java基础知识点总结.docx

    七、 接口(面向对象特征之一)★★★★ 28 八、 多态(面向对象特征之一)★★★★ 30 九、 java.lang.Object 31 十、 异常★★★★ 34 十一、 包(package) 37 十二、 多线程★★★★ 39 为什么要使用多线程 39 ...

    应用市场中Java拦截器和切面的使用实例详解

    主要介绍了应用市场中Java拦截器和切面的使用实例详解,具有一定借鉴价值,需要的朋友可以参考下

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    Java面试题-面向对象、多线程.pdf

    1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: ...总共90多道题目,包含面向对象、算法、多线程等面试题及详解 大厂面试题集,纯人工手写,分享不易,有问题敬请谅解 。。。。。。。。

    疯狂JAVA讲义

    6.6.6 面向接口编程 198 6.7 内部类 202 6.7.1 非静态内部类 202 学生提问:非静态内部类对象和外部类对象的关系是怎样的? 206 6.7.2 静态内部类 207 学生提问:为什么静态内部类实例方法也不能访问外部类的...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    Java编程老鸟潜心写作,奉献高效率的Java学习心得 完全站在没有编程经验读者的角度,手把手教会读者学习Java 配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让...

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    面向对象技术与UML课件及源代码-by 南邮-陈杨

    本书为中南大学精品教材立项项目,分为上下两篇共21章,涵盖了面向对象技术中Java开发环境配置、程序设计基础、面向对象原理以及UML的知识。本书使用的开发环境是JDK 1.6+Eclipse 3.3+Rational Rose 2003,逐步引领...

    【05-面向对象(下)】

    面向接口编程 •接口体现了规范与实现分离的原则。充分利用接口可以很好地提高系统的可扩展性和可维护性。 •接口与简单工厂模式、命令模式等。 内部类 •我们把一个类放在另一个类的内部...

    Java开发技术大全 电子版

    第2篇Java面向对象编程 第3章对象和类98 3.1面向对象的基本概念98 3.1.1对象98 3.1.2类99 3.1.3消息101 3.1.4面向对象的4个基本特征101 3.2类与对象104 3.2.1类的基本结构104 3.2.2类的声明104 3.2.3创建...

Global site tag (gtag.js) - Google Analytics