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

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);
?}
}

上面的輸出結果為:
Hello Wind!

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

當Music類中生成Instrument類時,看看編譯能不能通過:

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

結果編譯報錯:
Instrument 是抽象的;無法對其進行實例化

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