抽象類和抽象方法的產(chǎn)生在Thinking in Java里面闡述的非常清楚了,正如那個(gè)Instrument的例子,Instrument類的對象沒有任何意思,它是抽象的,定義在它里面的play()方法也是沒有意思的,之所以定義這個(gè)方法,是為了在它的繼承類中,可以用不同的方法類表示這個(gè)接口,產(chǎn)生不同的行為。為了防止客戶端調(diào)用了這個(gè)方法,也不會(huì)產(chǎn)生編譯錯(cuò)誤,但是執(zhí)行的結(jié)果不是客戶端所希望的,那么怎樣使得這樣的調(diào)用在編譯的時(shí)候就能發(fā)現(xiàn)問題,從而防止這種問題出現(xiàn)呢?解決的方法就是“抽象方法機(jī)制”。在方法前面加abstract關(guān)鍵詞:
??????????????????????????????????????abstract void f();
這個(gè)方法是不完整的,僅有申明沒有方法體。那么就變成了抽象類,如果一個(gè)類包含一個(gè)或多個(gè)抽象方法,那么此類就必須限定為abstract的,否則編譯器會(huì)報(bào)錯(cuò)。由于抽象類的不完整(抽象方法的不完整造成的)就不能產(chǎn)生該類的對象,編譯器就會(huì)產(chǎn)生報(bào)錯(cuò)。

abstract class Instrument{
?public abstract void play();
}

class Wind extends Instrument{
? public void play(){
? ?System.out.println("Hello Wind!");
? }
}

public class Music{
?public static void tune(Instrument i){
??i.play();
?}
?
?public static void main(String[] args){
??Wind w = new Wind();
??tune(w);
?}
}

上面的輸出結(jié)果為:
Hello Wind!

如果將Instrument的class前面abstract除掉就會(huì)產(chǎn)生編譯錯(cuò)誤:
Instrument 不是抽象的,并且未覆蓋 Instrument 中的抽象方法 play()

當(dāng)Music類中生成Instrument類時(shí),看看編譯能不能通過:

public class Music{
?public static void tune(Instrument i){
??i.play();
?}
?
?public static void main(String[] args){
??Wind w = new Wind();
??tune(w);
?}
}

結(jié)果編譯報(bào)錯(cuò):
Instrument 是抽象的;無法對其進(jìn)行實(shí)例化

縱上可以得到,所謂“抽象”的引入是為了防止我們產(chǎn)生錯(cuò)誤(或者說正確設(shè)計(jì)合適的類,沒有實(shí)際意思的類可以將其“抽象”),而且為繼承類提供統(tǒng)一接口。