abstract是一個修飾符,其類似于Static這樣的關(guān)鍵字。Android程序中常用abstract修飾一個類,如abstract class,當(dāng)然能它也可以修飾一些變量或是方法。
抽象類所包含的方法可以只是定義,也可以是已實現(xiàn)的。對于沒有實現(xiàn)的方法,基于該方法的子類必須實現(xiàn);而對于已經(jīng)實現(xiàn)的方法,子類可以重寫該方法,若沒有重寫,則使用父類的方法。
在一定程度上,abstract class可以代替Interface,例如,《Android Interface的使用》一文中,Interface的例子做如下的abstract class替換,其效果是等價的。
代碼清單1-1 InterfaceServer.java
public class InterfaceServer {
abstract class OnClickListener2{
public void onClick2();
}
private OnClickListener2 mOnClickListener2=null;
public void onClick2(){
if(mOnClickListener2!=null)
mOnClickListener2.onClick2();
}
public void setOnClickListener2(OnClickListener2 l){
mOnClickListener2 = l;
}
Abstractclass和 interface是Java語言中對于抽象類定義進行支持的兩種機制,正是由于這兩種機制的存在,才賦予了Java強大的面向?qū)ο竽芰Α?abstractclass和interface之間在對于抽象類定義的支持方面具有很大的相似性,甚至可以相互替換,因此很多開發(fā)者在進行抽象類定義時對于abstractclass和interface的選擇顯得比較隨意。其實,兩者之間還是有很大的區(qū)別的。
Interface與abstract class的區(qū)別
1.從語法角度講,接口和抽象類有以下區(qū)別:
·Java語法規(guī)定,一個子類只能有一個父類,但可以實現(xiàn)多個接口。
·abstract class可以代替Interface。
·定義Interface時,只需要列出所包含方法的定義而不必實現(xiàn)。而定義Abstract類時,方法必須有實現(xiàn)部分,這就是所謂的默認實現(xiàn),除非該方法也是Abstract類型。
·接口的子類必須實現(xiàn)接口所定義的全部方法,而抽象類的子類不必實現(xiàn)抽象類所定義的任何方法,除非該方法是Abstract或者子類想重寫某個方法。
·接口中的成員變量必須是Static Final類型(實際應(yīng)用中則很少包含變量,因為接口多用于引用),而abstract class內(nèi)部可以包含任意變量。
2.從應(yīng)用的角度來講,Interface和abstract class的區(qū)別在于:
·Interface提供了一個方法集合的接口,該接口用于客戶端和服務(wù)端的方法調(diào)用,如圖1-1所示。

圖1-1 Interface的使用機制
·接口一般是由服務(wù)端定義,比如操作系統(tǒng),客戶端根據(jù)自己的需求對接口做不同的實現(xiàn);而abstract class則僅提供了一個基類,該基類沒有任何服務(wù)端或者客戶端的概念,它的作用就是為了繼承并重寫,如圖1-2所示。

圖1-2 abstract class的使用機制
3.從編程的角度來看,abstract class和interface都可以用來實現(xiàn)"design by contract"的思想,但是在具體的使用上面還是有一些區(qū)別的:
·abstract class在Java語言中表示的是一種繼承關(guān)系,一個類只能使用一次繼承關(guān)系。但是,一個類卻可以實現(xiàn)多個interface。也許,這是Java語言的設(shè)計者在考慮Java對于多重繼承的支持方面的一種折中考慮吧。
·在abstract class的定義中,我們可以賦予方法的默認行為。但是在interface的定義中,方法卻不能擁有默認行為,為了繞過這個限制,必須使用委托,但是這會 增加一些復(fù)雜性,有時會造成很大的麻煩。
在抽象類中不能定義默認行為還存在另一個比較嚴重的問題,那就是可能會造成維護上的麻煩。因為如果后來想修改類的界面(一般通過abstract class或者interface來表示)以適應(yīng)新的情況(比如,添加新的方法或者給已用的方法中添加新的參數(shù))時,就會非常的麻煩,可能要花費很多的時間(對于派生類很多的情況,尤為如此)。但是如果界面是通過abstract class來實現(xiàn)的,那么可能就只需要修改定義在abstract class中的默認行為就可以了。
同樣,如果不能在抽象類中定義默認行為,就會導(dǎo)致同樣的方法實現(xiàn)出現(xiàn)在該抽象類的每一個派生類中,違反了"one rule,one place"原則,造成代碼重復(fù),同樣不利于以后的維護。因此,在abstract class和interface間進行選擇時要非常的小心。