抽象
介紹關鍵字 abstract 的用法及其物件導向意義。
何謂抽象? What is Abstract?
抽象可以想像成一種概念,並不存在於世界上。
在『多型』的章節中,我們有一個Animal的類別,但現實生活中有這個東西嗎? 動物只是一個概念,並沒有一種生物叫作動物。 狗、鳥、魚都是實際存在於世界上的實體,他們都是動物,現實中卻沒有一個實體叫作動物。
如果聽起來卡卡的,再反覆讀幾次。 所以我們可以把動物視為一種『概念』,他是抽象的,不存在於世界上的。 而Dog、Bird、Fish都具備這個概念的特質,所以繼承Animal。
關鍵字 abstract
abstract 是一個Java的關鍵字,是一個修飾子,可以用來修飾的有: 1. 類別 2. 方法
抽象類別 abstract class
利用abstract來修飾類別,可以使類別變成抽象類別,使用方法:
在類別定義前加上修飾子abstract,就可以定義抽象類別。
上面我們提到,抽象是一個概念,而不是一個存在的實體。同樣的,抽象類別不能被實體化。
範例程式,抽象類別定義:
範例程式,實體化測試:
執行結果:
發生編譯錯誤,因為抽象類別無法被實體化。
阿我設計類別就是為了實體化產生物件阿,現在跟我說這個類別無法被實體化那我幹嘛要寫? 先別急,這個抽象類別無法被實體化,但是他可以『被繼承』。
這樣Dog類別就有Animal類別定義好的東西,在加上他自己的成員,就可以用來創造Dog的物件。
因此可以說,抽象類別是用來被繼承的。
擁有這個概念的類別,繼承抽象類別,在程式撰寫上就可以利用多型的概念上程式更有邏輯性。
以上一篇『多型』的程式例子來說,Animal這個抽象的概念不應該被實體化,因為現實中不從在一種東西叫作『動物』,而狗、鳥、魚都是實際存在的東西,都擁有『動物』這個概念的特性,所以比較好的寫法應該定義為:
這樣寫很清楚告訴說,動物是一種概念,不能被實體化。而Dog、Bird、Fish具有動物的特性,可以被實體化存在於世界上(記憶體中)。
抽象方法 abstract method
利用修飾子abstract,可以使方法變成抽象方法,抽象方法只能寫方法的原型,無法定義方法的本體。
方法的原型? 只定義修飾子、回傳值型態、方法名稱、參數型態,而沒有『大括號{}』的部分就是方法原型。
方法的本體就是用『大括號{}』定義的東西,有寫{}就算有定義,不管裡面有沒有程式敘述。
使用格式:
範例:
錯誤範例:
好,那現在問題又來了,我要這個沒有本體的抽象方法幹嘛? 只有原型的方法做不了任何事阿!
沒錯,所以必須要有其他人『覆寫』這個抽象方法。
程式範例,定義Animal為抽象類別,有一個抽象方法eat():
在上述程式中,母類別Animal定義了一個抽象方法eat(),宣告這個eat()方法回傳值是void且不帶任何參數。 子類別必須覆寫這個方法,為這個方法定義本體,也就是『實作implement』這個方法。
特別注意的是,抽象方法只能定義在抽象類別中。 (否則會編譯錯誤)
abstract method can only be defined by an abstract class
有了抽象方法,那我們的抽象類別就可以定義的更簡潔了。
範例程式:
上述程式中,將Animal類別定義為抽象,裡面把eat()定義為抽象方法,任何繼承這個Animal的子類別都必須實作屬於他們自己的eat(),同時都擁有Animal所定義的成員。
這樣做的目的是因為繼承一個類別,子類別就可以當作母類別來使用,但一般母類別都定義的很一般化,所以透過abstract關鍵字『強制』子類別繼承這個母類別後必須實作屬於自己的方法,也讓物件導向的設計邏輯更符合一般的現實概念。
最後整理一下
關鍵字abstract,抽象,可以修飾:
類別
讓類別變成抽象類別,不能建立實體,專門用來『被繼承』。
方法
讓方法變成抽象方法,只能定義原型,專門用來『被覆寫』。
其中抽象方法只能被定義在抽象類別中。
Last updated