陳祥輝老師/撰文
很多人在學習Java物件導向程式設計時,或許在學習的初期都可以瞭解程序的執行順序以及流程的控制。但是,導入了物件導向觀念時,總會有許許多多的疑惑與不解。就像是遇到『類別』(Class)、『抽象類別』(Abstract Class)以及『介面』(Interface)時,常常就直接背下定義,卻難以理解使用時機與技巧,這都是沒有抓到脈絡的關係。
那麼到底什麼是『物件導向程式設計』(Object Oriented Programming,簡稱OOP)?沒有物件導向就不能寫程式嗎?答案當然不是這樣的。可以視『物件導向』為一種撰寫程式的方法,讓我們撰寫出來的程式可以更有結構性,並且提升程式的重覆使用性,延續其生命週期。『物件導向』其實就是一種『抽象化』的結果,所以只要瞭解什麼是『抽象化』,對於撰寫物件導向的程式語言,就只剩下基本的『語法』(Syntax)、『語意』(Semantic)以及寫作經驗。
在眾所周知的生物分類方法是使用『界、門、綱、目、科、屬、種』七層來做為分類標準,其實這種分類方式就已經是『抽象化』了。倘若將此順序依據『界』在上,『種』在下,就代表越往上越抽象化,越往下就越具體化。換句話說,越抽象的限制條件越少,越具體化的條件越多。所以『界』是分類法中的最抽象,『種』是分類法中的最具體化。相對地,在物件導向中的『繼承』(Inherit)與『實作』(implement)就是利用『抽象化』的過程,產生出來的一種靜態結構。相對地,Java程式中的『介面』(interfaces)不就是最抽象嗎?因為它最『空』,『抽象類別』(abstract Classes)其次,『類別』(classes)再其次,『物件』(objects)則是最具體了。
學習『物件導向程式』必須同時學習『統一塑模語言』(Unified Modeling Language, 簡稱UML)。因為寫Java程式是具體的,UML是用來看靜態結構、動態流程與行為模式,所以是抽象的。在學習的過程,除了具體地撰寫程式之外,同時也要透過UML的抽象來看整體架構,這樣才能學會『Top Down』(由上而下,或稱由抽象而具體)以及『Bottom Up』(由下而上,或稱由具體而抽象)的不同思考模式。
最後,我們利用UML的類別圖(Class Diagram)來思考兩個不同的簡單範例,針對兩個『飲料販賣機』與『扭蛋販賣機』類別,分別具有相同的『開機』與『關機』兩個功能以及一個『isPowerOn』的屬性,各自也有一個『選擇飲料』與『取蛋』的不同功能。
[範例1]各自撰寫各自的功能
當兩個類別各自撰寫時,會發現兩個相同的功能『開機』與『關機』要寫兩次,亦或是利用複製與貼上。一旦功能撰寫有誤,或是需求有變更時,就必須同時更改兩次程式碼。
[範例2]透過『繼承』方式將『共同的』功能與屬性抽離出來,亦就是『抽象化』。
可以將[Figure 1]框線內『共同的』功能與屬性抽離出來,並置入一個新的類別『販賣機』內,彼此之間再透過『繼承』方式,如圖Figure 2。由於『繼承』的關係,父類別具有的功能與屬性(除了private的功能與屬性以外),子類別皆會繼承,所以不論在撰寫或是維護,相同的功能只要維護一個父類別『販賣機』即可。
所以,在學習Java物件導向程式設計時,除了要有實際累積撰寫經驗之外,更需要透過『具體化』與『抽象化』之間不斷地轉換思考,才能讓自己所撰寫的程式更具有階層關係以及較完善的架構。