抽象类和接口的比较

来源:互联网 发布:gameloft java 编辑:程序博客网 时间:2024/06/06 16:44
 
abstract classinterfaceJava言中于抽象义进行支持的两种机制,正是由于两种机制的存在,才予了Java大的面向象能力。abstract classinterface于抽象的支持方面具有很大的相似性,甚至可以相互替,因此很多开者在行抽象义时对abstract classinterface选择显得比随意。,两者之间还是有很大的区的,于它选择甚至反映出问题领域本的理解、设计的理解是否正确、合理。本文将的区别进行一番剖析,试图给者提供一个在二者之间进选择的依据。
理解抽象
abstract classinterfaceJava言中都是用来行抽象(本文中的抽象并非从abstract class而来,它表示的是一个抽象体,而abstract classJava言中用于定抽象的一种方法,请读者注意区分)定的,那么什么是抽象,使用抽象们带来什么好呢?
在面向象的概念中,我知道所有的象都是通过类来描的,但是反来却不是这样。并不是所有的都是用来描绘对象的,如果一个中没有包含足的信息来描一个具体的象,这样就是抽象。抽象往往用来表征我对问题领行分析、设计中得出的抽象概念,是一系列看上去不同,但是本上相同的具体概念的抽象。比如:如果我们进行一个编辑软件的开,就会发现问题领域存在着、三角形这样一些具体概念,它是不同的,但是它又都属于形状这样一个概念,形状个概念在问题领域是不存在的,它就是一个抽象概念。正是因抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象是不能够实例化的。
在面向域,抽象主要用来藏。我可以构造出一个固定的一的抽象描述,但是这组却能有任意个可能的具体实现方式。个抽象描述就是抽象,而任意个可能的具体实现则现为所有可能的派生。模可以操作一个抽象体。由于模于一个固定的抽象体,因此它可以是不允修改的;同,通个抽象体派生,也可展此模的行功能。熟悉OCP者一定知道,了能够实现面向设计的一个最核心的原OCP(Open-Closed Principle),抽象是其中的关所在。
法定义层面看abstract classinterface
面,Javaabstract classinterface出了不同的定方式,下面以定一个名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 classinterface法定义层面更多的细节问题,不是本文的重点,不再述,者可以参参考文献〔1得更多的相关内容。
面看abstract classinterface
程的角度来看,abstract classinterface都可以用来实现"design by contract"的思想。但是在具体的使用上面是有一些区的。
首先,abstract classJava言中表示的是一种承关系,一个只能使用一次承关系。但是,一个却可以实现多个interface。也Java言的设计者在考Java于多重承的支持方面的一种折中考吧。
其次,在abstract class的定中,我可以予方法的默。但是在interface的定中,方法却不能有默绕过这个限制,必使用委托,但是增加一些复性,有会造成很大的麻
在抽象中不能定为还存在另一个比较严重的问题,那就是可能会造成维护上的麻。因如果后来想修改的界面(一般通abstract class或者interface来表示)以适新的情况(比如,添加新的方法或者已用的方法中添加新的参数),就会非常的麻,可能要花很多的时间于派生很多的情况,尤如此)。但是如果界面是通abstract class实现的,那么可能就只需要修改定abstract class中的默就可以了。
,如果不能在抽象中定,就会致同的方实现抽象的每一个派生中,反了"one ruleone place",造成代重复,同不利于以后的维护。因此,在abstract classinterface间进选择时要非常的小心。
设计理念面看abstract classinterface
上面主要从法定程的角度述了abstract classinterface的区面的区是比次的、非本的。本小将从另一个面:abstract classinterface所反映出的设计理念,来分析一下二者的区。作者认为,从行分析才能理解二者概念的本所在。
前面已提到abstarct classJava言中体了一种承关系,要想使得承关系合理,父和派生存在"is a"关系,即父和派生在概念本应该是相同的(参考文献〔3〕中有关于"is a"关系的大篇幅深入的述,有趣的者可以参考)。interface 说则不然,并不要求interface实现者和interface在概念本上是一致的,仅仅实现interface的契而已。了使述便于理解,下面将通一个简单明。
虑这样一个例子,假在我问题领域中有一个关于Door的抽象概念,Door具有行两个openclose,此可以通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 classinterface没有大的区
如果在要求Door要具有警的功能。我们该如何设计针对该例子的类结构呢(在本例中,主要是了展示abstract classinterface反映在设计理念上的区,其他方面无关的问题都做了化或者忽略)?下面将列出可能的解决方案,并从设计理念对这些不同的方案行分析。
解决方案一:
简单的在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() { … }
 
种方法反了面向设计中的一个核心原ISPInterface Segregation Principle),在Door的定中把Door概念本身固有的行方法和另外一个概念"警器"的行方法混在了一起。这样引起的一个问题是那些仅仅Door个概念的模会因"警器"个概念的改(比如:修改alarm方法的参数)而改,反之依然。
解决方案二:
既然openclosealarm属于两个不同的概念,根据ISP则应该把它在代表两个概念的抽象中。定方式有:两个概念都使用abstract class方式定;两个概念都使用interface方式定;一个概念使用abstract class方式定,另一个概念使用interface方式定
然,由于Java言不支持多重承,所以两个概念都使用abstract class方式定是不可行的。后面两种方式都是可行的,但是于它选择却反映出问题领域中的概念本的理解、设计的反映是否正确、合理。我一一来分析、明。
如果两个概念都使用interface方式来定,那么就反映出两个问题1、我可能没有理解清楚问题领域,AlarmDoor在概念本上到底是Door警器?2、如果我们对问题领域的理解没有问题,比如:我过对问题领域的分析发现AlarmDoor在概念本上和Door是一致的,那么我实现时就没有能正确的揭示我设计,因两个概念的定上(均使用interface方式定)反映不出上述含
如果我们对问题领域的理解是:AlarmDoor在概念本上是Door,同它有具有警的功能。我们该如何来设计实现来明确的反映出我的意思呢?前面已经说过abstract classJava言中表示一种承关系,而承关系在本上是"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 classinterfaceJava言中的两种定抽象的方式,它有很大的相似性。但是于它选择却又往往反映出问题领域中的概念本的理解、设计的反映是否正确、合理,因了概念的不同的关系(然都能够实现需求的功能)。也是言的一种的用法,希望者朋友能够细细体会