- 浏览: 81377 次
- 性别:
- 来自: 珠海
文章分类
最新评论
-
kennyluo:
网页上发布的代码上缺少了"//",注意&q ...
apply a Texture Image to a Cube -
kyng:
图片放到目录下。。。修改对应名称 。。怎么还出错!!!
Ex ...
apply a Texture Image to a Cube
选择接口还是抽象类
理解接口和抽象类的选择原则,有两个概念很重要:对象的行为和对象的实现。如果一个实体可以有多种实现方式,则在设计实体行为的描述方式时,应当达到这样一个目标:在使用实体的时候,无需详细了解实体行为的实现方式。也就是说,要把对象的行为和对象的实现分离开来。既然Java的接口和抽象类都可以定义不提供具体实现的方法,在分离对象的行为和对象的实现时,到底应该使用接口还是使用抽象类呢?
通过抽象类建立行为模型
在接口和抽象类的选择上,必须遵守这样一个原则:行为模型应该总是通过接口而不是抽象类定义。为了说明其原因,下面试着通过抽象类建立行为模型,看看会出现什么问题。
假设要为销售部门设计一个软件,这个软件包含一个“发动机”(Motor)实体。显然无法在发动机对象中详细地描述发动机的方方面面,只能描述某些对当前软件来说重要的特征。至于发动机的哪些特征是重要的,则要与用户(销售部门)交流才能确定。
销售部门的人要求每一个发动机都有一个称为马力的参数。对于他们来说,这是惟一值得关心的参数。基于这一判断,可以把发动机的行为定义为以下行为。
行为1:查询发动机的马力,发动机将返回一个表示马力的整数。
虽然现在还不清楚发动机如何取得马力这个参数,但可以肯定发动机一定支持这个行为,而且这是所有发动机惟一值得关注的行为特征。这个行为特征既可以用接口定义,也可以用抽象类定义。为了说明用抽象类定义可能出现的问题,下面用抽象类建立发动机的行为模型,并用Java方法描述行为1,代码如下:
public abstract Motor{
abstract public int getHorsepower();
}
在Motor抽象类的基础上构造出多种具体实现,例如A型发动机、B型发动机等,再加上系统的其它部分,最后得到1.0版的软件并交付使用。一段时间过去了,现在要设计2.0版的软件。在评估2.0版软件需求的过程中,发现一小部分发动机是电池驱动的,而电池需要一定的充电时间。销售部门的人希望能够通过计算机查阅充电时间。根据这一要求定义一个新的行为,如图1所示。
行为2:查询电驱动发动机的充电时间,发动机将返回一个表示充电时间的整数。
用Java方法来描述这个行为,代码如下:
public abstract BatteryPoweredMotor extends Motor{
abstract public int getTimeToRecharge();
}
在销售部门的软件中,电驱动发动机也以类的形式实现,但这些类从BatteryPoweredMotor而不是Motor派生。这些改动加入到2.0版软件之后,销售部门很满意。随着业务的不断发展,不久之后光驱动的发动机出现了。销售部门要求光驱动发动机需要一定光能才能运转,光能以流明(Lumen)度量。这个信息对客户很重要,因为下雨或多云的天气里,某些光驱动发动机可能无法运转。销售部门要求为软件增加对光驱动发动机的支持,所以要定义一个新的行为。
行为3:查询光驱动发动机能够正常运转所需要的最小流明数,发动机返回一个整数。
再定义一个抽象类并把行为3转换成Java方法,代码如下:
public abstract SolarPoweredMotor extends Motor{
abstract public int getLumensToOperate();
如图1所示,SolarPoweredMotor和BatteryPoweredMotor都从Motor抽象类派生。在整个软件中,90%以上的代码以相同的方式对待所有的发动机。偶尔需要检查一下发动机是光驱动还是电驱动,使用instanceof实现,代码如下:
[color=#336600]
if (instanceof SolarPoweredMotor){...}
if (instanceof BatteryPoweredMotor){...}
无论是哪种发动机,马力这个参数都很重要,所以在所有派生的抽象类(SolarPoweredMotor和BatteryPoweredMotor)中,getHorsepower()方法都有效。
现在销售部门又有了一种新的发动机,它是一种既有电驱动又有光驱动的双重驱动发动机。光驱动和电驱动的行为本身没有变化,但新的发动机同时支持两种行为。在考虑如何定义新型的光电驱动发动机时,接口和抽象类的差别开始显示出来了。新的目标是在增加新型发动机的前提下尽量少改动代码。因为与光驱动发动机、电驱动发动机有关的代码已经过全面的测试,不存在已知的Bug。为了增加光电驱动发动机,要定义一个新的SolarBatteryPowered抽象类。如果让SolarBatteryPowered从Motor抽象类派生,SolarBatteryPowered将不支持针对光驱动发动机和电驱动发动机的instanceof操作。也就是说,如果查询一个光电驱动的发动机是光驱动的,还是电驱动的,得到的答案是:都不是。
如果让SolarBatteryPowered从SolarPoweredMotor(或BatteryPoweredMotor)抽象类派生,类似的问题也会出现,SolarBatteryPowered将不支持针对BatteryPoweredMotor(或SolarPoweredMotor)的instanceof操作。从行为上看,光电驱动的发动机必须同时从两个抽象类派生,但Java语言不允许多重继承。之所以会出现这个问题,根本的原因在于使用抽象类不仅意味着定义特定的行为,而且意味着定义实现的模式。也就是说,应该定义一个发动机如何获得行为的模型,而不仅仅是声明发动机具有某一个行为。
通过接口建立行为模型
如果用接口来建立行为模型,就可以避免隐含地规定实现模式。例如,前面的几个行为改用接口定义如下。
行为1:
public interface Motor(){
public int getHorsepower();
}
行为2:
public interface BatteryPoweredMotor extends Motor(){
public int getTimeToRecharge();
}
行为3:
public interface SolarPoweredMotor extends Motor{
abstract public int getLumensToOperate();
}
现在光电驱动的发动机可以描述为:
public DualPoweredMotor implements SolarPoweredMotor, BatteryPoweredMotor{}
DualPoweredMotor只继承行为定义,而不是行为的实现模式,如图2所示。
在使用接口的同时仍旧可以使用抽象类,不过这时抽象类的作用是实现行为,而不是定义行为。只要实现行为的类遵从接口定义,即使它改变了父抽象类,也不用改变其它代码与之交互的方式。特别是对于公用的实现代码,抽象类有它的优点。抽象类能够保证实现的层次关系,避免代码重复。然而,即使在使用抽象类的场合,也不要忽视通过接口定义行为模型的原则。从实践的角度来看,如果依赖于抽象类来定义行为,往往导致过于复杂的继承关系,而通过接口定义行为能够更有效地分离行为与实现,为代码的维护和修改带来方便。
发表评论
-
FastReport问题整理
2012-06-09 19:58 3235部分来自网上,部分 ... -
关于C# WinForm FastReport Studio的使用方法:
2012-06-09 19:56 2354using System; using System. ... -
FastReport studio 动态加载数据集 (zhuan)
2012-06-09 19:56 1290测试使用的FastReport S ... -
[转载]了解IL反编译工具Ildasm.exe
2012-05-29 22:06 0Ildasm.exe 的使用方法 示例: 在应用 ... -
从ipa提取图片资源,还原PNG文件
2012-05-14 15:44 5114iOS 开发过程中,在code和测试阶段结束后,你需要用xco ... -
PHP缓存技术:memcache函数详解之一
2012-02-14 04:59 967Memcache函数库是在PECL( ... -
PHP缓存技术:memcache函数详解之二
2012-02-14 04:56 1284memcache::debug bool memcac ... -
PHP企业级应用之常见缓存技术篇
2012-02-14 04:50 1206php的缓冲器: 有eaccelerator, apc ... -
php缓存技术详解
2012-02-14 04:48 893一、缓存技术: 有些信息比方经常不变的,但是还是 ... -
PHP企业级应用之常见缓存技术篇
2012-02-14 04:47 810别每天OO,这个配置怎么改,这段代码哪错了,没劲,好的程 ... -
FreeFileSync 文件比较同步系统
2012-02-04 00:06 1241http://sourceforge.net/proj ... -
[图文]Openfiler应用篇(五)Accounts之AD认证
2012-02-03 20:16 1238一、Win2003服务器域控制器准备 首先 ... -
[图文]Openfiler应用篇(四) FTP和Quota
2012-02-03 20:14 2278本篇我们讨论openfiler FTP ... -
[图文]Openfiler应用篇(三) Accounts
2012-02-03 20:12 943openfiler帐户(Accounts)设置,是openfi ... -
[图文]Openfiler应用篇(二) SMB/CIFS server
2012-02-03 20:12 1339一、建立share-1逻辑卷 本篇我们讨论openfile ... -
[图文]Openfiler应用篇(一)iSCSI
2012-02-03 20:11 1320本文主要讲解Openfile iSCSI 设置和应用,首 ... -
手机产品交互设计样式
2012-01-28 15:51 822很多人都说,手机产品交互限制因素很多,过小的屏幕分辨率, ... -
Domain Locking SWFs
2011-08-12 14:05 809By domain locking (or site lock ... -
CentOS系统下如何打开端口
2011-07-21 10:48 1120在CentOS系统使用中,我们会遇到很多的问题。例如CentO ... -
基于角色管理的系统访问控制(2)
2010-02-21 11:24 1116方案设计 3.1. 安全保护 ...
相关推荐
### 面向接口编程与Java接口、抽象类的选择 #### 一、接口与抽象类的概念 ...总之,无论是选择接口还是抽象类,都需要根据实际需求和设计原则来决定。面向接口编程有助于构建出更加灵活、可扩展和易于维护的系统。
选择接口还是抽象类主要取决于以下因素: 1. 多继承:如果语言支持多继承,如Java,且你需要从多个源头获得行为,那么接口可能是更好的选择,因为一个类可以实现多个接口。而在Java中,一个类只能继承一个抽象类。 ...
选择使用接口还是抽象类取决于具体的设计需求: - 如果需要定义一个操作的集合,且不需要提供任何具体实现,则使用**接口**。 - 如果需要提供一些通用的实现,并希望子类继承这些行为,那么使用**抽象类**。 - 如果...
接口与抽象类区别 在软件开发中,接口和抽象类是两个常用的概念,但它们之间的区别却让许多人感到困惑。那么,什么是抽象类和接口?它们之间有什么区别?下面,我们就来详细地探讨这个问题。 一、抽象类 抽象类是...
选择使用接口还是抽象类取决于具体的应用场景: 1. **当需要定义一组行为规范时:**应该使用接口。这样可以让多个不相关的类实现相同的行为,增强程序的灵活性和扩展性。 2. **当需要提供部分实现或共享状态时:**...
### 详细解析Java中抽象类和接口的区别 #### 引言 在面向对象编程中,Java作为一种广泛应用的编程语言,提供了多种方式来实现抽象的概念。其中最常用的两种机制是抽象类(abstract class)和接口(interface)。这...
在了解了接口和抽象类的定义和使用格式之后,我们可以根据以下几点来选择使用接口还是抽象类: 1. **成员实现详情**:抽象类可以提供成员的实现详情,而接口不能。如果你希望在抽象类中提供某些方法的默认实现,则...
Java 接口和抽象类 Java 编程语言提供了两种机制来实现面向对象编程的多态性:接口和抽象类。这两种机制使得 Java 应用开发具有灵活性和敏捷性。 抽象类 抽象类是一种特殊的类,它不能被实例化,不能被直接使用,...
在C#编程语言中,类、接口、虚...在选择使用抽象类还是接口时,应根据项目需求和设计原则来权衡。例如,如果需要共享部分实现并有继承关系,可以选择抽象类;如果需要多个类实现一组共同行为,接口可能是更好的选择。
在选择使用抽象类还是接口时,需要根据实际需求权衡。如果需要共享代码和方法,或者希望强制子类实现特定行为,抽象类是合适的选择。如果希望解耦系统,提供更灵活的扩展性,或者保护实现的细节,接口是更好的选择。
在Java编程语言中,接口(Interface)和抽象类(Abstract Class)都是用于实现多态性的关键概念,它们各自有特定的用途和优缺点。本文将深入探讨这两种概念,帮助你理解它们之间的区别以及如何在实际开发中选择使用...
11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别.zip11.java接口和抽象类的区别....
C#类、接口、虚方法和抽象方法-接口与抽象类的区别实例 C#类、接口、虚方法和抽象方法-接口与抽象类的区别实例
java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例...
接口与抽象类的选择取决于具体的设计需求。如果关注的是行为的规范,且可能有多个实现者,那么接口是更好的选择。如果需要共享实现细节或者提供默认行为,抽象类则更为合适。 在压缩包中的"抽象类与接口"文件中,你...
10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和抽象类的相似性.zip10.java接口和...
在实际开发中,我们通常会根据需求来选择使用抽象类还是接口。如果需要为一组相关的类提供公共的属性和方法实现,抽象类是一个很好的选择。而当需要定义一组行为规范,让不同类群实现这些行为时,接口就显得更为合适...
在实际编程中,接口和抽象类的选择通常取决于特定场景的需求。如果需要为一组有共同行为的类提供基本实现,并且这些类之间存在继承关系,那么抽象类可能是更好的选择。另一方面,如果需要定义一组独立的契约,或者一...
本文将深入探讨“接口抽象类”的主题,包括它们的概念、用途、区别以及在Java编程语言中的实现。 首先,让我们了解什么是接口。接口在Java中是一种完全抽象的类型,它只包含方法签名(方法名、返回类型和参数列表)...