OO世界裡一直是真實世界的縮影,在真實世界中並非所有的事物皆可具體化,既然如此OO中當然也產生了不可實體化的類別來對應描述之,我們謂之『抽象類別』。

 

說也奇怪,竟有某些名詞實際上找不到存在的實體。在真實世界中並非所有事物皆可產生具體化的實體。舉例來說:你曾經看過某個實體稱之為『動物』嗎?我想應該沒有吧!你看到的想必是『人』、『狗』、『獅子』嗯嗯我想你能瞭解了哈。動物只是一個較高抽象化的名詞,他規範了一件事:只要會移動就叫做動物,真正可實體化的是動物底下的細部分類,例如:人、狗、獅子、老虎等等。既然真正看的到的是人、狗等實體,為何需要有動物這個抽象化的名詞呢~我們試著想一個場景,今天你到了一個園區裡面有獅子、老虎、熊各式各樣的生物在裡面,你怎麼用一句話來形容呢我想就是需要用一個更為抽象的詞彙可以涵蓋這些生物來形容此時此景吧,因此『挖~園區裡有好多動物喔』可以將前述的現象一語蔽之…see!一切就變的如此自然了。

 

記得!越抽象的詞彙越能簡化描述,當對方有興趣時才針對細節作探討,這也大大簡化了人們之間溝通的效率。先用抽象的描述,有共識再來看細節。在想想一個場景,今天你想約另一個朋友去動物園,你會說:ㄟ~要不要去看熊、獅子、老虎、狗…ooxx…這樣的陳述嗎?我想不會吧!你應該只會說:ㄟ~要不要去動物園。哈~夠簡單吧,這就是為什麼要有抽象名詞存在的意義。先提大方向,只要當對方有興趣他就會進一步問你細部內容,也就是這樣溝通的效率才能越來越有效率。

 

噹噹噹~抽象類別登場!既然OO是現實生活的縮影,那上述的抽象名詞既然存在,當然OO中也要有配套措施那就是利用『抽象類別(abstract class)』。那到底什麼叫抽象類別,在Java中的定義很簡單,只要類別中有一個或一個以上的方法是抽象方法(abstract method)那這個類別就必須宣告為抽象類別。所謂抽象方法是指a method not include implementation code,也就是此方法只有定義沒有實做,在講白話一點,回到動物的例子,動物應該會有一個方法叫做『move()』,但move()的內容該如何做呢,別問我~我也不曉得~天曉得動物會怎麼走路~哈。也許是用爬、走、游、跑,既然不知道那就先定義就好,不要針對他的內容實做吧!stop…回過頭來,我們是在探討抽象類別吧,既然抽象類別中會有抽象方法,那他就不適合被具體化(也就是不能產生物件),以下例而言:

abstract class Animal {

  public abstract void move();

}

Animal a = new Animal(); à 這會有問題的,compiler error occurs

為什麼會有error呢,試想如果今天真的讓你產生出一個動物的實體叫做a,當我呼叫a.move(),慘囉~move()是抽象方法,並沒有實際的運作程式碼,因此產生出來也無法使用,既然如此~當然也不用產生囉!

 

抽象類別的適用時機。下面分兩點說明,第一:我想抽象類別的存在就如同上述抽象名詞的概念,我們都希望說的越少但能表示的越多,而抽象化能幫助我們達到此一目標。相對的,在程式的世界中若想讓程式寫的越少卻能涵蓋的越多,那就要善用抽象類別,搭配前面我曾說過的多型一起使用,將可以達到:用越少的程式達到越多的效果。第二:抽象類別中的抽象方法具備了規範的效果,當有一類別繼承了抽象類別,那勢必需要將抽象方法的內容重新定義(我們將此稱為『overriding),這樣我們可以確保繼承抽象類別的子類別全部都會有抽象類別中的抽象方法重新定義之method。等等~我想讀者已經頭暈了,換個實例說明,Animal是個抽象類別,當要繼承這個抽象類別時,必須把move() overriding,亦即將move的內容定義出來,如果是人那就是走路、獅子就是四條腿移動、魚就是游動,當你沒有重新定義函式,compiler會自動偵測並且回報錯誤來提醒工程師,這樣一來我們可以放心的用Animal這個抽象類別來動態操作下面的子類別囉~~

 

善用抽象吧,越抽象往往威力越大。能否理解用抽象反轉來操控底層的實體,是衡量一程式設計師是否具備優良的工匠技藝的關鍵指標之一。

創作者介紹
創作者 劉逸 的頭像
劉逸

劉逸的留意世界

劉逸 發表在 痞客邦 留言(1) 人氣()


留言列表 (1)

發表留言
  • 低調粉絲
  • 好深奧的議題...@@
    睡覺時會滿腦子抽象抽象抽象~~