抽象类和接口的比较

 
abstract class interface Java 言中 于抽象 义进 行支持的两种机制,正是由于 两种机制的存在,才 予了 Java 大的面向 象能力。 abstract class interface 于抽象 的支持方面具有很大的相似性,甚至可以相互替 ,因此很多开 者在 行抽象 义时对 abstract class interface 选择显 得比 随意。 ,两者之 间还 是有很 大的区 的, 于它 选择 甚至反映出 问题领 域本 的理解、 设计 的理解是否正确、合理。本文将 的区 别进 行一番剖析, 试图给 者提供一个在二者之 间进 选择 的依据。
理解抽象
abstract class interface Java 言中都是用来 行抽象 (本文中的抽象 并非从 abstract class 而来,它表示的是一个抽象体,而 abstract class Java 言中用于定 抽象 的一种方法, 请读 者注意区分)定 的,那么什么是抽象 ,使用抽象 们带 来什么好 呢?
在面向 象的概念中,我 知道所有的 象都是通 过类 来描 的,但是反 来却不是 这样 。并不是所有的 都是用来描 绘对 象的,如果一个 中没有包含足 的信息来描 一个具体的 象, 这样 就是抽象 。抽象 往往用来表征我 对问题领 行分析、 设计 中得出的抽象概念,是 一系列看上去不同,但是本 上相同的具体概念的抽象。比如:如果我 们进 行一个 编辑软 件的开 ,就会 发现问题领 域存在着 、三角形 这样 一些具体概念,它 是不同的,但是它 又都属于形状 这样 一个概念,形状 个概念在 问题领 域是不存在的,它就是一个抽象概念。正是因 抽象的 概念在 问题领 域没有 对应 的具体概念,所以用以表征抽象概念的抽象 是不能 够实 例化的。
在面向 域,抽象 主要用来 藏。我 可以构造出一个固定的一 的抽象描述,但是 这组 却能 有任意个可能的具体 实现 方式。 个抽象描述就是抽象 ,而 任意个可能的具体 实现则 现为 所有可能的派生 。模 可以操作一个抽象体。由于模 于一个固定的抽象体,因此它可以是不允 修改的;同 ,通 个抽象体派生,也可 展此模 的行 功能。熟悉 OCP 者一定知道, 了能 够实现 面向 设计 的一个最核心的原 OCP(Open-Closed Principle) ,抽象 是其中的关 所在。
法定 义层 面看 abstract class interface
面, Java abstract class interface 出了不同的定 方式,下面以定 一个名 Demo 的抽象 类为 例来 种不同。
使用 abstract class 的方式定 Demo 抽象 的方式如下:
abstract class Demo
abstract void method1();
abstract void method2();

 
使用 interface 的方式定 Demo 抽象 的方式如下:
interface Demo {
void method1();
void method2();

}
 
abstract class 方式中, Demo 可以有自己的数据成 ,也可以有非 abstarct 的成 方法,而在 interface 方式的 实现 中, Demo 只能 有静 的不能被修改的数据成 (也就是必 static final 的,不 interface 中一般不定 数据成 ),所有的成 方法都是 abstract 的。从某种意 interface 是一种特殊形式的 abstract class
abstract class interface 法定 义层 面更多的 细节问题 ,不是本文的重点,不再 述, 者可以参 参考文献〔 1 得更多的相关内容。
面看 abstract class interface
程的角度来看, abstract class interface 都可以用来 实现 "design by contract" 的思想。 但是在具体的使用上面 是有一些区 的。
首先, abstract class Java 言中表示的是一种 承关系,一个 只能使用一次 承关系。但是,一个 却可以 实现 多个 interface 。也 Java 言的 设计 者在考 Java 于多重 承的支持方面的一种折中考 吧。
其次,在 abstract class 的定 中,我 可以 予方法的默 。但是在 interface 的定 中,方法却不能 有默 绕过这 个限制,必 使用委托,但是 增加一些复 性,有 会造成很大的麻
在抽象 中不能定 为还 存在另一个比 较严 重的 问题 ,那就是可能会造成 维护 上的麻 。因 如果后来想修改 的界面(一般通 abstract class 或者 interface 来表示)以适 新的情况(比如,添加新的方法或者 已用的方法中添加新的参数) ,就会非常的麻 ,可能要花 很多的 时间 于派生 很多的情况,尤 如此)。但是如果界面是通 abstract class 实现 的,那么可能就只需要修改定 abstract class 中的默 就可以了。
,如果不能在抽象 中定 ,就会 致同 的方 实现 抽象 的每一个派生 中, 反了 "one rule one place" ,造成代 重复,同 不利于以后的 维护 。因此,在 abstract class interface 间进 选择时 要非常的小心。
设计 理念 面看 abstract class interface
上面主要从 法定 程的角度 述了 abstract class interface 的区 面的区 是比 次的、非本 的。本小 将从另一个 面: abstract class interface 所反映出的 设计 理念,来分析一下 二者的区 。作者 认为 ,从 行分析才能理解二者概念的本 所在。
前面已 提到 abstarct class Java 言中体 了一种 承关系,要想使得 承关系合理,父 和派生 存在 "is a" 关系,即父 和派生 在概念本 应该 是相同的(参考文献〔 3 〕中有关于 "is a" 关系的大篇幅深入的 述,有 趣的 者可以参考)。 interface 说则 不然,并不要求 interface 实现 者和 interface 在概念本 上是一致的, 仅仅 实现 interface 的契 而已。 了使 述便 于理解,下面将通 一个 简单 明。
虑这样 一个例子,假 在我 问题领 域中有一个关于 Door 的抽象概念, Door 具有 行两个 open close ,此 可以通 abstract class 或者 interface 来定 一个表示 抽象概念的 型,定 方式分 如下所示:
使用 abstract class 方式定 Door
abstract class Door {
abstract void open();
abstract void close()

}
 
使用 interface 方式定 Door
interface Door {
void open();
void close();
}
 
其他具体的 Door 型可以 extends 使用 abstract class 方式定 Door 或者 implements 使用 interface 方式定 Door 。看起来好像使用 abstract class interface 没有大的区
如果 在要求 Door 要具有 警的功能。我 们该 如何 设计针对该 例子的 类结 构呢(在本例中,主要是 了展示 abstract class interface 反映在 设计 理念上的区 ,其他方面无关的 问题 都做了 化或者忽略)?下面将 列出可能的解决方案,并从 设计 理念 对这 些不同的方案 行分析。
解决方案一:
简单 的在 Door 的定 中增加一个 alarm 方法,如下:
abstract class Door {
abstract void open();
abstract void close()

abstract void alarm();
}
 
或者
interface Door {
void open();
void close();
void alarm();
}
 
那么具有 警功能的 AlarmDoor 的定 方式如下:
class AlarmDoor extends Door {
void open() { … }
void close() { … }
void alarm() { … }
}
 
或者
class AlarmDoor implements Door
void open() { … }
void close() { … }
void alarm() { … }
 
种方法 反了面向 设计 中的一个核心原 ISP Interface Segregation Principle ),在 Door 的定 中把 Door 概念本身固有的行 方法和另外一个概念 " 警器 " 的行 方法混在了一起。 这样 引起的一个 问题 是那些 仅仅 Door 个概念的模 会因 " 警器 " 个概念的改 (比如:修改 alarm 方法的参数)而改 ,反之依然。
解决方案二:
既然 open close alarm 属于两个不同的概念,根据 ISP 则应该 把它 在代表 两个概念的抽象 中。定 方式有: 两个概念都使用 abstract class 方式定 ;两个概念都使用 interface 方式定 ;一个概念使用 abstract class 方式定 ,另一个概念使用 interface 方式定
然,由于 Java 言不支持多重 承,所以两个概念都使用 abstract class 方式定 是不可行的。 后面两种方式都是可行的,但是 于它 选择 却反映出 问题领 域中的概念本 的理解、 设计 的反映是否正确、合理。我 一一来分析、 明。
如果两个概念都使用 interface 方式来定 ,那么就反映出两个 问题 1 、我 可能没有理解清楚 问题领 域, AlarmDoor 在概念本 上到底是 Door 警器? 2 、如果我 们对 问题领 域的理解没有 问题 ,比如:我 过对 问题领 域的分析 发现 AlarmDoor 在概念本 上和 Door 是一致的,那么我 实现时 就没有能 正确的揭示我 设计 ,因 两个概念的定 上(均使用 interface 方式定 )反映不出上述含
如果我 们对 问题领 域的理解是: AlarmDoor 在概念本 上是 Door ,同 它有具有 警的功能。我 们该 如何来 设计 实现 来明确的反映出我 的意思呢?前面已 经说过 abstract class Java 言中表示一种 承关系,而 承关系在本 上是 "is a" 关系。所以 Door 个概念,我 们应该 使用 abstarct class 方式来定 。另外, AlarmDoor 又具有 警功能, 明它又能 完成 警概念中定 的行 ,所以 警概念可以通 interface 方式定 如下所示:
abstract class Door {
abstract void open();
abstract void close()

}
interface Alarm {
void alarm();
}
class AlarmDoor extends Door implements Alarm {
void open() { … }
void close() { … }
void alarm() { … }
}
实现 方式基本上能 明确的反映出我 们对 问题领 域的理解,正确的揭示我 设计 。其 abstract class 表示的是 "is a" 关系, interface 表示的是 "like a" 关系,大家在 选择时 可以作 一个依据,当然 是建立在 对问题领 域的理解上的,比如:如果我 们认为 AlarmDoor 在概念本 警器,同 又具有 Door 的功能,那么上述的定 方式就要反 来了。
结论
abstract class interface Java 言中的两种定 抽象 的方式,它 有很大的相似性。但是 于它 选择 却又往往反映出 问题领 域中的概念本 的理解、 设计 的反映是否正确、合理,因 了概念 的不同的关系( 然都能 够实现 需求的功能)。 也是 言的一种的 用法,希望 者朋友能 够细细 体会
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值