??????? 在Java語(yǔ)言中,可以定義一種抽象類型,并且提供這種這一抽象類型的各種具體實(shí)現(xiàn)。實(shí)際上Java給我們提供不只是一種機(jī)制而是兩種讓我們可以做到這一點(diǎn)。它們是Java接口和Java抽象類。二者的區(qū)別如下:
?????? (1) 兩者最明顯的區(qū)別在于,Java抽象類可以提供部分方法的實(shí)現(xiàn),而Java接口不能。這是Java抽象類的有點(diǎn)也是優(yōu)勢(shì)。如果向一個(gè)抽象類加入一個(gè)新的具體的方法,那么所有的子類一下子就得到了這個(gè)新的具體的方法。如果向一個(gè)接口中加入一個(gè)新的方法,所有實(shí)現(xiàn)這個(gè)接口的類都不能全部成功的通過(guò)編譯,因?yàn)樗鼈儧](méi)有實(shí)現(xiàn)這個(gè)新聲明的方法。這就是Java接口的一個(gè)缺點(diǎn)了。
?????? (2) 一個(gè)抽象類的實(shí)現(xiàn)只能由這個(gè)抽象類的子類給出,那么,這個(gè)實(shí)現(xiàn)出在抽象類所定義出的繼承的等級(jí)結(jié)構(gòu)中,而由于Java語(yǔ)言限制多繼承,因此抽象類作為類型定義工具的效果就大打折扣了。反之,任何一個(gè)實(shí)現(xiàn)了Java接口所規(guī)定的方法的類都可以具有這個(gè)接口的類型,而一個(gè)類可以實(shí)現(xiàn)多個(gè)接口。這也是兩者最重要的區(qū)別之一。
????? (3) 從代碼重構(gòu)的角度上看,將一個(gè)單獨(dú)的Java具體類重構(gòu)為一個(gè)Java接口的實(shí)現(xiàn)是很容易的。我們只需要聲明一個(gè)接口,并將重要的方法添家到接口聲明中,然后在具體的類定義語(yǔ)句后加上一個(gè)何時(shí)的implments就OK了。而為一個(gè)已有的具體類添加一個(gè)抽象類作為抽象類型卻不是那么的容易了,因?yàn)檫@個(gè)具體類有可能已經(jīng)有了一個(gè)超類,這樣以來(lái),這個(gè)新定義的抽象類只好繼續(xù)向上移動(dòng),變成這個(gè)超類的超類,如此循環(huán),最后這個(gè)新定義的抽象類必定處于整個(gè)等級(jí)類型結(jié)構(gòu)的最上端,從而使得等級(jí)結(jié)構(gòu)中的所有成員都受到影響。
????? (4)?Java接口是定義混合類型的理想工具。Mixin Type就是在一個(gè)類主類型之外的次類型。一個(gè)混合類表明一個(gè)類不僅具有主類型的行為,而且還具有其它的行為。比如Hashtabl類就具有多個(gè)類型。它的主類型為Map,這是一種Java聚集。而Cloneable接口則給出了一個(gè)次要類型,這個(gè)類型說(shuō)明這個(gè)類是可以安全克隆的。同樣,Serializable也是一個(gè)次要類型,它表明這個(gè)類是可以串行化的。