- 浏览: 288252 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
yhxf_ie:
网上都是这个方法 改了之后仍然无效啊! 真急人
让Gradle支持中文 -- 关于 "编码 GBK 的不可映射字符"错误的解决 -
smart152819:
夜行侠老师gradle教学视频地址:http://www.it ...
Gradle笔记 -
laorer:
gradle init --type pom
MAVEN项目秒变Gradle项目 -
sulpha:
Gradle 2.0以上,需要把Compile改为JavaCo ...
让Gradle支持中文 -- 关于 "编码 GBK 的不可映射字符"错误的解决 -
marshan:
默认情况下都报错 没有setupBuild这个task 楼主提 ...
MAVEN项目秒变Gradle项目
Java接口与Java抽象类的区别:
1. Java抽象类可提供某些方法的实现,而Java接口则不行;
2. Java抽象类中增加一个具体的方法,则子类都具有此具体方法,Java接口中新增加方法,则子类必须实现此方法;
3. 在Java中,子类最多能继承一个抽象类,而一个类可以实现多个接口;
4. 从代码重构角度考虑,将一个具体类重构为一个Java接口的实现容易,因为一个类可实现多个接口;而将一个具体类重构为抽象类的实现不容易,因为一个类只能继承一个抽象类;
5. 接口可定义类的多种类型。
关于java接口与抽象类,大家经常谈到他们的区别,而这区别仅仅是针对语法结构上的区别,但是对于如何选择接口和抽象类确还不是很清楚,下面有篇文章还不错,是讲解如何选择接口和抽象类的,可以借鉴学习一下。
很多人有过这样的疑问:为什么有的地方必须使用接口而不是抽象类,而在另一些地方,又必须使用抽象类而不是接口呢?或者说,在考虑Java类的一般化问题时,很多人会在接口和抽象类之间犹豫不决,甚至随便选择一种。
实际上接口和抽象类的选择不是随心所欲的。 要理解接口和抽象类的选择原则,有两个概念很重要:对象的行为和对象的实现。如果一个实体可以有多种实现方式,则在设计实体行为的描述方式时,应当达到这样一个目标:在使用实体的时候,无需详细了解实体行为的实现方式。也就是说,要把对象的行为和对象的实现分离开来。既然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();
- }
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实现,代码如下:
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 interface SolarPoweredMotor extends Motor{ abstract public int getLumensToOperate(); }
现在光电驱动的发动机可以描述为:
public DualPoweredMotor implements SolarPoweredMotor, BatteryPoweredMotor{}
DualPoweredMotor只继承行为定义,而不是行为的实现模式,如图2所示。
在使用接口的同时仍旧可以使用抽象类,不过这时抽象类的作用是实现行为,而不是定义行为。只要实现行为的类遵从接口定义,即使它改变了父抽象类,也不用改变其它代码与之交互的方式。特别是对于公用的实现代码,抽象类有它的优点。抽象类能够保证实现的层次关系,避免代码重复。然而,即使在使用抽象类的场合,也不要忽视通过接口定义行为模型的原则。从实践的角度来看,如果依赖于抽象类来定义行为,往往导致过于复杂的继承关系,而通过接口定义行为能够更有效地分离行为与实现,为代码的维护和修改带来方便。
发表评论
-
Gradle笔记
2012-10-30 08:21 368076.1 每个构建包含一个或多个 "Proj ... -
Mybatis+Proxool+Spring多数据源切换
2012-08-10 13:57 6905话不多说直接上代码,用者自提,不喜勿喷,3Q < ... -
JSTL 学习、应用记录
2011-07-28 14:34 1225JSTL 学习、应用记录 原来一直没有看过,我说过我是新 ... -
Spring两大核心-AOP和IoC
2011-07-11 10:43 1427Spring两大核心-AOP和 ... -
java内存泄露解析
2011-07-11 10:42 1546原因有很多种, ... -
Java 反射机制
2011-07-11 10:41 1021Java 反射机制 摘要 Reflecti ... -
java 23种设计模式
2011-07-11 10:40 870工厂模式, 工厂方法模式,单例模式, 外观(Facad ... -
Class.forName和New的比较
2011-07-11 10:36 1151Class.forName和New的比较 ... -
null或空值的判断处理-java
2011-07-11 10:33 1404null或空值的判断处理-java 原帖地址 ... -
java中字符串链接性能比较
2011-07-11 10:31 1206原帖地址:http://blog.csdn.net/bes ... -
[转]提高Java反射速度的方法以及对setAccessable的误解
2011-05-30 15:20 2003mercyblitz 写道 ouchxp 写道 ... -
用MyElipse配置WebLogic
2011-04-12 16:16 1363(1)安装Weblogic设置如下: 首先建立domai ... -
Myeclipse9.0正式版下载地址(附破解包)
2011-04-12 11:09 4590用者自提,谢绝乱喷 Windows http:// ... -
C#之int挑战Java之Integer
2010-10-25 16:55 1913C#之int挑战Java之Integer ... -
是 String , StringBuffer 还是 StringBuilder ?
2010-07-06 09:39 1147相信大家对 String 和 StringBuffer 的 ... -
JAVA程序员葵花宝典
2010-03-31 08:54 1241话不多说,先下载再说^^ -
Struts2笔记 - 10 自定义类型转换器
2010-02-10 17:05 1047package struts2.demo.action; ... -
Struts2笔记 - 09 请求参数的接收
2010-02-10 15:21 1443采用基本类型接收请求参数(get/post)在Action类中 ... -
Struts2笔记 - 08配置多个Struts配置文件
2010-02-10 14:54 1159动态方法调用和使用通配符定义 由请求参数指定调用action ... -
Struts2笔记 - 07 配置多个Struts配置文件
2010-02-08 16:13 1021配置多个Struts配置文件 <struts> ...
相关推荐
总结而言,选择抽象类还是接口取决于具体的应用场景和需求。在设计系统架构时,理解并正确使用这两种工具是非常重要的。抽象类和接口的合理运用能够帮助我们更好地组织代码,提高代码的复用性和可维护性。
在实际应用中,选择抽象类还是接口通常取决于设计需求: - 当需要共享一些共同的实现代码时,抽象类是一个好选择,因为它们可以提供部分实现。 - 如果希望一个类实现多种行为,或者在不支持多重继承的语言中模拟...
在选择抽象类还是接口时,应考虑以下因素: 1. 是否需要提供默认实现?如果需要,抽象类可能是更好的选择。 2. 是否希望一个类能同时继承自另一个类并实现多个特性?如果是,应使用接口。 3. 是否关注类型系统和...
在实际项目设计过程中,到底是选择抽象类还是接口呢?它们的选择反映出对于需求本质的合理理解和设计意图的正确理解。 抽象类是Java语言中的一种机制,可以用来描绘一个抽象的父类对象,例如动物(Animal)类,它...
选择使用抽象类还是接口取决于实际需求: 1. **单一职责**:当一个类需要承担单一职责时,可以考虑使用接口;当一个类需要承担多种职责时,可以考虑使用抽象类。 2. **行为扩展**:如果希望在不修改现有代码的基础上...
选择使用抽象类还是接口主要取决于具体的需求: - 如果需要共享代码实现,同时保持某些方法未实现,则使用抽象类。 - 如果需要定义多个类共同的行为规范,但不需要共享任何具体的实现,则使用接口。 - 当一个类需要...
选择抽象类还是接口取决于几个关键因素: - **继承层次结构**:如果你的系统有一个清晰的继承层次结构,抽象类可能更适合,因为它可以提供共享行为和状态。 - **多态需求**:如果需要一个类从多个源继承行为,使用...
接口与抽象类的选择取决于具体的设计需求。如果关注的是行为的规范,且可能有多个实现者,那么接口是更好的选择。如果需要共享实现细节或者提供默认行为,抽象类则更为合适。 在压缩包中的"抽象类与接口"文件中,你...
在Java编程中,抽象类和接口是两种不同的机制,用于实现代码的多态性和抽象性。...选择抽象类还是接口取决于设计目标和问题领域的具体需求,抽象类适合表达概念上的继承关系,而接口则更适合定义行为规范和契约。
在C#编程语言中,类、接口、虚...在选择使用抽象类还是接口时,应根据项目需求和设计原则来权衡。例如,如果需要共享部分实现并有继承关系,可以选择抽象类;如果需要多个类实现一组共同行为,接口可能是更好的选择。
在实际开发中,选择抽象类还是接口取决于具体需求。如果预计未来会有多个版本的组件,抽象类是不错的选择,因为它提供版本控制的灵活性。如果需要在广泛不同的对象间共享功能,接口更为合适。对于大型功能模块,抽象...
### 详细解析Java中抽象类和接口的区别 #### 引言 在面向对象编程中,Java作为一种广泛应用的编程语言,提供了多种方式来实现抽象的概念。其中最常用的两种机制是抽象类(abstract class)和接口(interface)。这...
最后,面对选择抽象类还是接口的问题,通常的指导原则是:如果类之间存在继承关系,且有共享属性或方法,应使用抽象类;如果需要实现多种行为,或者多个类需要遵循相同的协议,应选择接口。 总的来说,Java的抽象类...
Java抽象类与接口实验报告
java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例...
抽象类和接口实验报告
从战略角度看,选择抽象类还是接口取决于具体的设计需求: 1. **单一职责原则**:如果一个类只承担一种职责,那么抽象类可能更合适。因为它允许部分实现,子类只需覆盖或添加特定功能即可。 2. **扩展性**:如果...
abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进 行抽象类定义时对于abstract class和interface的选择显得比较随意。其实,两者之间还是有很大的...