java接口的作用和抽象类的区别

Java中接口和抽象类的区别
在语言中,
abstract class 和&是支持定义的两种机制。正是由于这两种机制的存在,才赋予了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可以有自己的数据成员,也可以有非
abstract的成员方法,而在interface方式的实现中,Demo只能够有静态的不能被修改的数据成员(也就是必须是static
的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。从某种意义上说,interface是一种特殊形式的
abstract class。
  从编程的角度来看,abstract
class和interface都可以用来实现 "design by contract"
的思想。但是在具体的使用上面还是有一些区别的。
 首先,abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系(因为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所反映出的设计理念,来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概念的本质所在。
  前面已经提到过,abstract
class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"-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 Alarm Door extends Door implements Alarm{
void open(){…}
void close(){…}
void alarm(){…}
 这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其 实abstract
class表示的是"is-a"关系,interface表示的是"like-a"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。
  1.abstract
class 在 Java
语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。
 2.在abstract class
中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是
static final的,不过在
interface中一般不定义数据成员),所有的成员方法都是abstract的。
  3.abstract
class和interface所反映出的设计理念不同。其实abstract
class表示的是"is-a"关系,interface表示的是"like-a"关系。
  4.实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
  .接口中定义的变量默认是public
static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
  6.抽象类中的变量默认是
friendly 型,其值可以在子类中重新定义,也可以重新赋值。
  7.接口中的方法默认都是
public,abstract 类型的。
 abstract class 和 interface 是
Java语言中的两种定义抽象类的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系(虽然都能够实现需求的功能)。这其实也是语言的一种的惯用法,希望读者朋友能够细细体会。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。Java基础——抽象类和接口的关系_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Java基础——抽象类和接口的关系
来源:Linux社区&
作者:郝贵宝
在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是并不是所有的类都能用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就应该被定义为抽象类。
& & & & 比如,我们要描述&动物&,它具有年龄、体积,会叫,能跑。但是又缺乏足够的特性(相较于阿猫,阿狗,它们都是动物,却有自己的特性),我们没有唯一的一种能够代表动物的东西(当然,这是相对于猫、狗来说的,在生物学上,动物还是有办法来定义的),这时我们可以用抽象类来描述它。当我们用某个类来具体描述&猫&时,这个类就可以继承&动物&这个抽象类,然后加以具体描述。抽象类的子类在类中必须实现抽象类中的抽象方法,比如说动物类中的跑和叫,在子类中(猫类,狗类)必须实现其是如何跑,怎么叫。抽象方法没有方法体,且用abstract修饰。
下面我们来系统的介绍一下抽象类:
a.& & & 抽象方法和抽象类用关键字abstract表示。
b.& & & 抽象类不能被实例化
c.& & & 有抽象方法的类一定是抽象类(或者接口);抽象类中不一定有抽象方法。
d.& & & 如果一个类继承抽象类,那么这个类要么本身也是抽象类,要么这个类重写父类的所有抽象方法。
强制要求子类必须完成某些功能。
A.& & &成员变量 -- 可以有成员变量,也可以有常量
B.& & &构造方法 -- 有构造方法,用于子类访问父类之前,对父类数据进行初始化。
C.& & &成员方法 -- 可以有抽象方法,也可以有关非抽象方法。
& & & & & & & & & & & & & & &i.& & & & & &抽象方法是为了要求子类做某些事情。
& & & & & & & & & & & & & &ii.& & & & & &非抽象方法时为了提高代码复用性,被子类继承。
& & & & &注意:
& & & & &不能与final、private、static 共存。
抽象类(abstract class)的定义方式如下:
public abstract class AbstractClass& & & & & &
//里面至少有一个抽象方法{&  & //普通数据成员   public abstract void method1();& //抽象方法,抽象类的子类在类中必须实现抽象类中的抽象方法&  public abstract void method2();&  public void method3();& & & //非抽象方法& & & &
publicvoid method3(){& &
  &&& & & //抽象类中可以赋予非抽象方法方法的默认行为,即方法的具体实现&  } }
& & & 是一种特殊的抽象类。比抽象类更抽象,因为它里面的方法都是抽象的。
& & & Class 类名& implements 接口名
A.& & & &接口不能实例化。
B.& & & &接口中的方法:
a)& & & & 要么被子类重写
b)& & & & 要么子类也是抽象类。
& & & & & &成员变量 -- 接口中只有常量。
& & & & & & & & & &因为接口的成员变量有默认修饰符。推荐:永远自己给出修饰符,public static& final
& & & & & &构造方法 -- 接口中没有构造方法。
& & & & & & & & & &任何类如果没有继承父类,那么这个类就继承Object类
& & & & & &成员方法 -- 接口中的方法都是抽象的。&
& & & & & & & & & & 因为接口中的 成员方法有默认修饰符。推荐:永远自己给出修饰符,public abstract
思想特点:
1.& & & & 对外暴露的规则。
2.& & & & 程序的功能扩展
3.& & & & 降低耦合性
4.& & & & 用来多实现。&
接口(interface)的定义方式如下:
interface Interface{ &  publi& //接口中不能有普通数据成员,只能够有静态的不能被修改的数据成员,static表示全局,final表示不可修改,可以不用static final 修饰,会隐式的声明为static和final,但是建议永远自己给出修饰符public static& final  public abstract void method1();& //接口中的方法一定是抽象方法,所以可以不用abstract修饰,但是建议永远自己给出修饰符public abstract&  public void method2();& //接口中不能赋予方法的默认行为,即不能有方法的具体实现。(注意,此处及省略了abstract.)}class zi implements Interface{& & & &
publicvoid method1()& & & &
{& & & & & & & & &
&&& & & & & & & & &
//把接口中的抽象方法重写& & & &
public void method2()& & & &
{& & & & & & & & & &&& & & & & & & & &
//注意,是把抽象方法全部重写(接口里的方法全部是抽象方法)& & & & & }}&//另一种情况,子类也是抽象类,此时可以不重写接口中的方法/*abstract& class zi& implements Interface{& & & &
public abstract void method1();& & & & & & & & //没有重写& & & & & & & &
public& void method2()& & & & & & & & & & & & & & &
//重写了method2()& & & &
{& & & & & & & & &
System.out.println("重写了method2()");& & & &
抽象类与接口的对比&
&成员特点&
&成员变量&
变量或常量
默认修饰符 public static final
&构造方法&
&成员方法&
抽象方法或非抽象方法
默认修饰符public abstract
&设计理念&
& & 被继承,定义的是整个继承体系的共性内容&
& & &被实现,定义的是整个体系的扩展内容&
&关系特点&
& 继承关系,只能单继承,可以多层继承
& 实现关系,可以单实现,也可以多实现。还可以继承一个类的同时,实现多个接口。
& &接口与接口&
& 继承关系,可以单继承,也可以多 继承。
进一步理解,关于Java中引入抽象类、接口的目的,度娘上有高手的答复如下:&
1、从类的层次结构上看,抽象类是在层次的顶端,但在实际的设计当中,一般来说抽象类应当是后面才会出现。为什么?实际上抽象类的获取有点像数学中的提取公因式:ax+bx,x就是抽象类,如果你没有前面的式子,你怎么知道x是不是公因式呢?在这点上,也符合人们认识世界的过程,先具体后抽象。因此在设计过程中如果你得到大量的具体概念并从当中找到其共性时,这个共性的集合就是抽象类应当是没错的。
2、interface从表面上看,和抽象类很相似,但用法完全不同。它的基本功能就是把一些毫不相关的类(概念)集合在一起形成一个新的、可集中操作的&新类&。一个典型的例子就是&司机&。谁可以当司机??谁都可以,只要领取了驾照。所以不管你是学生,白领、蓝领还是老板,只要有驾照就是司机。
interface DriverLicence {& && & & & Licence getLicence();& &}&class StudentDriver extends Student implements DriverLicence&{}class WhtieCollarEmployeeDriver extends WhtieCollarEmployee implements DriverLicence& {}class BlueCollarEmployeeDriver extends BlueCollarEmployee implements DriverLicence& {}class BossDriver extends Boss implements DriverLicence& &{}&
当我定义了&汽车&类后,我就可以指定&司机&了。
class Car {& & &
setDriver(DriverLicence driver); }
这时候,Car的对象并不关心这个司机到底是干什么的,他们的唯一共同点是领取了驾照(都实现了DriverLicence接口)。这个应当是接口最强大的地方也是抽象类无法比拟的。&
& & & & 抽象类是提取具体类的公因式,而接口是为了将一些不相关的类&杂凑&成一个共同的群体,因而实用性可能更高一点。两者的出现一方面是减少了代码量,提高了效率,另一方面照应前面提到的继承和多态,使得程序符合面向对象的思想特点,对修改关闭,对拓展开放。
本文永久更新链接地址:
相关资讯 & & &
& (02月23日)
& (02月23日)
& (06月29日)
& (02月23日)
& (02月23日)
图片资讯 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款JAVA基础之详细解析抽象类和接口的区别-c/c++-电脑编程网JAVA基础之详细解析抽象类和接口的区别作者:我学习Java的空间,记录Java历程的点滴! 和相关&&
  abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于abstract class和interface的选择显得比较随意。其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意图的理解是否正确、合理。本文将对它们之间的区别进行一番剖析,试图给开发者提供一个在二者之间进行选择的依据。理解抽象类&  abstract和interface在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都可以用来实现&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&关系,即父类和派生类在概念本质上应该是相同的。对于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还要具有报警的功能。我们该如何设计针对该例子的类结构呢?下面将罗列出可能的解决方案,并从设计理念层面对这些不同的方案进行分析。 解决方案一: 简单的在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 Priciple),在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语言中的两种定义抽象类的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系(虽然都能够实现需求的功能)。这其实也是语言的一种的惯用法,希望读者朋友能够细细体会。&   &
相关资料:|||||||JAVA基础之详细解析抽象类和接口的区别来源网络,如有侵权请告知,即处理!编程Tags:                &                    

我要回帖

更多关于 黎活明 的文章

 

随机推荐