物件 (Object) 的媽媽是 類別 (Class)?

從 OOP 學習物件導向(Object-oriented)觀念時,你就不太容易去對一些基本的 “術語 (terminology)”,下功夫來去 “參透” 其本質的意涵。例如,我雖然已經許久沒有教授基本物件觀念的課程,但在教授類別圖(Class Diagram)與物件圖(Object Diagram)時,多少就需要複習與說明什麼是類別,什麼又是物件。尤其,我最喜歡 “考” 程式設計的老手們,一個他們認為再基本與簡單不過的問題了: 物件是由誰誕生的?

嘿,如我預料,十個有九個回答:是由其所屬的類別誕生的。 是嗎? 我再請他們反思一個問題: 到底類別與物件的區別是什麼? 有人會回答:類別是死的;物件是活的。 這更有趣了,既然類別是死的,那麼,死的類別怎又能如何誕生出活的物件呢?

物件是有機的生命體,但類別卻不是,事實上,世界上根本就沒有 “類別” 這種有機體;而若是類別不是有機的生命體,那麼,物件就絕對不可能是由其誕生的!

為何會有公司、部門、員工等類別? 因為容易讓組織的層次分明,這是一種 “人工” 的分類;為什麼從狒狒的角度看人,就知道 “非我族類”? 因為這就是一種與生俱來的 “本能”,沒有任何理由,是再自然不過、也不用說明的道理了。所以,將 “物件” 分門別類,可以是 “人為判斷”,也可能是一種再自然不過的 “本能”,沒有絕對的標準,要將物件歸為那一類,只能說,要將物件分屬為某一類,你要能作比較 “合理化” 的說明而已。

看似再簡單不過的問題,其實才真正是蘊含極為深奧的哲理,要能具體說明類別與物件的區別,這其實比想像得還困難。首先,你可必須先徹底思考,到底什麼是類別,為什麼需要有類別,要如何分類 …等。關於類別,我會就我個人幾年來持續思考的體悟與認知,另外著文說明。”類別” 這個主題,絕對是在物件導向觀念中,最為關鍵的核心,因為,決定資訊系統因應需求變動而所能承受的震盪程度,取決於類別圖的設計,真正的軟體行家,如 Peter Coad 與 Martin Fowler,非常擅長將問題領域(Problem Domain)的概念(Concepts),抽象(abstract)化並依其本質與特性 “分門別類”,具化並組成為軟體內部的靜態結構,得以支撐系統的穩定、彈性與延展度。

回歸主題,到底物件是由誰誕生的呢?
我們先看底下一行程式碼,試著想想看,這一行程式碼的意思是什麼。

 Employee e = new Employee();

我在某討論區看到有人是作類似這樣的解釋: 用 Employee “類別” 造出一個 “物件實體” e ,這樣的回答,其實仍與物件是由其所屬的類別所誕生的意思是一樣的。

“Thinking in Java” 一書中,起碼還作了比較合理的說明:
You must create all the objects (所有物件都必須由你建立)

那個 “你” 是程式設計者? 我寧願作這樣的解釋:
程式設計者(Programmer)透過 new 關鍵字來要求「請給我一個新物件」。

既然是 “請”,也就代表了,程式設計者只是作宣告(Declare)而已,真正 “誕生” 物件者,其實就是 “系統”!,再說得白一點,就是應用伺服器(Application Server),或者,我個人蠻喜歡用 “Container” 這個術語,來說明應用程式其實就是透過它來取得系統層次的服務(System-level services),包括誕生物件等。

透過上述的說明,上面那一行程式碼比較合理的解釋應該像是這樣:
“個體(Instance) e 透過 new 關鍵字宣告,請系統(System)建立一個新物件,並將其分屬於 Employee 類別 (也就是具備了 Employee 類別所應有的 “本能”)。”

至於 “Instance” 一詞,本質就是物件,國內一般書籍翻譯為 “實例”,我很不喜歡,覺得不自然,也不夠貼近英文原意;翻譯成 “個體” 或 “實體”,應該是比較恰當的,而個體代表的就是,一個個的物件是可以獨立運作、為有機的生命體,瞭解(know) “something” 以及做(do) “something”。

對了,”系統(System)” 這個字眼,若以比較 “擬人化” 的術語,那未,我覺得「駭客任務」電影中,那個 “母體(Martix)” 應該會是最佳的代名詞了。 🙂

延伸閱讀
不要從程式語言學習物件導向!

文章導覽

   

共有 18 則迴響

  1. 類別到底是不是有機體?
    在〈物件 (Object) 的媽媽是 類別 (Class)?〉一文中,Kenming 兄提到「物件是有機的生命體,但類別卻不是,事實上,世界上根本就沒有『類別』這種有機體;而若是類別不是有機的生命體,那麼…

  2. Steven 提:
    “這樣的說法對於物件導向的學習有什麼幫助嗎?”

    物件導向 學習過程中重在 思考

    如果只是以結果論(輸入 –> 處理 –> 輸出),

    不用物件導向程式也寫的出來,可以跑.
    ————————————-
    建立類別的目的我覺得在於方便溝通思考.

    物件(Instance)是存在於 runtime 環境的記憶體中的,
    一旦系統不見了,物件自然就消失了.

  3. Hi 同人:

    有機會再聊~

    Hi 鳥毅:
    我不是大師,我只是會去思考一些基本的問題而已。
    不過確實這種基本的問題,許多程式設計師並沒有用心去思考的,我認為,這是屬於軟體設計的基礎功,慢慢地,未來就知道這種基礎功夫會反映在實做上的。

  4. 王大師,看來是有不少人搞不清楚狀況,你才會寫出來。Programmer都應該要清楚Instance的本質,才能寫出好的code呀!

  5. 太好了,

    看那天有空,順便找Simon,很久沒跟他聊有的沒有的了.

    閒聊間,往往會激出一些火花,通常都是意外之喜.^^

  6. Hi 同人:

    我的本意並不是在討論或爭論或有分歧關於類別與實例等哲學問題。

    不過,前天在授課時,有一位學員也很喜歡談論有與無等哲理思考問題,我向他說了,我認識的朋友就有一位(就是您)對此有很深闢的見解。所以他也蠻想認識您的,找個機會讓您們見個面,意趣相合,可以好好討論滴~ ^^

  7. 這個議題看了很久,感覺有點像看柏拉圖式的理型概念與亞理斯多德的邏輯之辯。就像亞理斯多德認為理型或型式是不存在的,就如同類別與實例本來無一物,是由我們觀察認為可以藉由它們來解決軟體開發的問題。我想這是Willian與克明兄觀點最大的分歧點吧?

    牽扯到哲學與形而上,是很難解釋的清楚的。不過在實際開發程式的過程中,倒是需要歸納與演繹相互運用,沒有人敢說柏拉圖式或亞理斯多德式才是對的方法。關鍵不在於類別或物件是否有機,而在於開發者的思考是否有機?這點古人釋易說得好:易一名有三易,曰易、曰不易、曰變易。循著簡單變化的道理,不變的是法則而非形式,而且法則是會跟隨著您想解決的問題核心(目的因)而有所不同。

    軟體的進展是一連串的變異所形成的自我組織,使得軟體開發並不是簡單系統,實體與類別或許會再演化,結果是如何沒人會了解,但每個演化都是簡單而單純的,也就是使得整個系統獲得最大效益,這是我們所確知的事,讓我們懷著期待的心情觀賞並加入演化吧。

  8. Hi william:

    高老師是我啟蒙的導師,在軟體設計上,我個人非常非常尊重他,甚至,我覺得他絕對是不亞於 Booch 的大師級的 Mentor。很多人說他很務虛,但當時在他的團隊時,一點我都不覺得,甚至,他其實很多別人以為是 “清談”、無法具化的概念,有很多還是我當時協助他寫成程式來具化的。

    至於所謂 Steven 提問的有何幫助,個人會是以為,強調的還是思考過程的收穫,而非結果,這應該與國內傳統教育要求答案的作法會很有落差吧? 在本篇文章最前述有提到,若 10 個有 9 個程式設計的老手都會認為物件是由類別誕生的,這,我會覺得軟體的基礎功夫是否不佳? 是否學習的方向有問題? 當然,極有可能是我個人過於偏執吧。(我可能就不太相信這樣能寫得好程式?)

    其實我早已很確定, william 您應該是走核心技術,的確,那非常需要走在平台技術的最前端,若沒有熱情與興趣是很難堅持下來的。而以我個人而言,應該是比較認同 MISOO 高煥堂老師所畫下的大餅:台灣往軟體設計來走;實做技術與大陸的高手們合作,但,可不是只作所謂的前段-後段, top-down 那種方式,而是軟體設計,根留台灣,我們比較傾向往這個願景努力。

    我們是否也是走太多人要走的路? 我好像也沒看過別人在走這條路耶? 業務面的實踐? 不清楚您的意思? 說真的,我們這樣一路走來,並不輕鬆,應該說是很不輕鬆,要面臨太多太多的挑戰與問題了,在過程中,難免也有很多不愉快的經驗,只是,當我一想到阿扁,意志力如此地堅強,我就覺得,這些不愉快根本不算什麼,心態慢慢調適,慢慢也就習慣囉。

    其實我非常清楚我們的方向與 william 您或許多國內 java 眾多高手所走的方向大不相同,甚至,還與國內倡導一些物件導向的軟體公司們完全是兩回事。但,其實最起碼仍有個共同點:對軟體是有熱情與興趣的。那就好了,這點最重要,每一個人對他所要走的路,找出自己的方向,堅持,保持意志力,盡量不要與現實妥協,這樣就很好了。

    而對於實做面的技術,以我個人,是非常有興趣學習與請教的,這點可不是禮貌性或敷衍。例如,若 william 您肯就 AOP+UC 的觀念能向您請教,我絕對會請您吃牛排加上喝咖啡的。聊這些議題,我永遠有空,也永遠有興趣的。說真的,我們約個時間,我作東,可否請教您這些問題呢? 這絕對是個很棒的討論! (對於求知慾,個人仍是蠻強烈的。 ^^)

  9. kenming:

    為了怕避免誤會,我得趕緊補上一句:我一點也不覺得你不務實(雖然有時我會覺得你「清談」的時候太高煥堂了些…)。

    可能因為這篇文章只是一則隨筆,可能因為這只是你系列文章的起頭,還來不及闡述些 Steven 所問的「這樣的說法對於物件導向的學習有什麼幫助」的實用議題吧。

    我之所以「會對實體平台技術面的核心很有興趣」,本身偏好固然是原因之一,另一個原因可能是身在資科/資工系多年,不得不對此層次持續關注吧。當然啦,有興趣又有能力對此層次鑽研並闡述的人,在台灣大概還不太多,這也可以算是一種差異化的市場區隔吧,畢竟我不太喜歡走太多人走的路。

    至於業務面的實踐,你們才是大師。 🙂

  10. Hi william:

    您誤解了,我更重視「務實」喔,尤其以我們這一行,若不徹底實踐,的確常被別人以為僅是 “清談” 而已。

    所謂的層次,是指我們會專注在哪一個焦點,例如,有人會專注在 INTEL CPU 的核心設計;也有人會專注在華碩主機板的設計,其實只是這樣,沒有所謂的高低與貴賤(有點擔心您會誤會所謂層次二字)。

    我會問您最後那一段的意思也是在於,個人會比較以為若把 App Server 當作是核心,而若牽涉到內部的核心結構設計,那會是比較貼近 INTEL 的角色;而若是把 App Server 當作是整合設計一環中的 “Supporter”,那麼,可能會是比較貼近整合的角色,此時,我們會觀察它的特性與功能,而比較不傾向研究至內部面的結構問題。

    william 您給我的感覺比較像是與侯捷大師那個方向是一致的,會對實體平台技術面的核心很有興趣與心得,所以看了您很多文章,的確在平台面的實體技術很有自己的心得與體會。但我個人,由於是往架構面的整體來走,反而會對比較軟性的議題較專注,應該比較接近是華碩主機板的角色吧?

    平台不是沒有研究,但肯定沒有您瞭解得如此透徹,事實上,個人的確蠻希望能就某些議題請教您,例如得知您在 AOP 與 UC 的議題上有很透徹的見解,光這點,我非常非常熱切想請教您。(例如,Security Model 與業務面 UC 的設計議題)

    個人是這麼覺得:「不同的層次,傳不同層次的法」,但其實本質都是一樣的,只是我們一般人,無法瞭解到所有層面到很深入的階段,可能需要採取互補的方式,會比較妥當吧?

    這一篇文章的主題,其實我知道多少會引起一些爭議,本意是想提供給物件學習的新手們一個思考的方向,我仍強調,答案的正確與否,不會是那麼重要,而是在思考的過程,這才有價值。

    不過,我有在思考,爾後可能不要用一些尖銳、批判式的方式來寫文章,容易引起誤解,甚至導致衝突或不愉快,這可就非我所願啦。 !^^

  11. Kenming:

    可能因為我個人的偏好吧,我喜歡清談,不過在面對大眾時,我更喜歡思考清談之後的實踐;畢竟普羅大眾的腦袋很少能夠在抽象層次思考之後,立即內化成短期或長期的應用能力。

    譬如說你文中的一段話:

    物件是有機的生命體,但類別卻不是,事實上,世界上根本就沒有 “類別” 這種有機體;而若是類別不是有機的生命體,那麼,物件就絕對不可能是由其誕生的!

    說實在的,這不管是在生命科學層次、哲學層次還是在電腦實踐層次,都未必有標準答案。

    暫且回到討論串的正題吧。

    你提到:

    我相信在實做面的技術,為了穩定與效能等考量,會把 Class 當成 Object 來用,那麼,Class 在該應用平台是否也是 “Instance” ?

    這要看該系統的 metaprogramming 層次有多高而定。在 Smalltalk 裡,的確是可以的。

    最後,我既關心「在應用伺服器系統的內部運作與其設計」,也關心「將 App Server 當成是系統服務的 Provider」。這兩種議題都很有趣,不是嗎?

  12. Hi william:
    這是思考層級的問題囉,可能我所思考類別與物件的觀念,在於更抽象於程式語言、甚而應用系統的實做面問題。

    我相信在實做面的技術,為了穩定與效能等考量,會把 Class 當成 Object 來用,那麼,Class 在該應用平台是否也是 “Instance” ?

    另,有趣的是,許多進階的程式人員,喜歡利用如 Singleton 來產生單一的 Instance,認為可以解決效能等問題,但問題是,是否有同時考量到 App Server 可能已經提供了 “Object Pooling” 機制,是否程式人員是 “多此一舉” 呢?

    所以,Yes, object 的生命週期,受 container 掌控的程度遠超出以往的想像,這也代表了,分權的確立,系統層級的服務,由系統來負責;軟性議題,包括問題領域的結構設計與需求等,由軟體設計師來負責。

    其實,william 您可以思考的是,您所關心的,會是在應用伺服器系統的內部運作與其設計,還是僅將 App Server 當成是系統服務的 Provider?

    這同時也就導致了我們思考的角度、方向、抽象層級,甚而學習的路線都不一樣了。

  13. Hi Steven:
    我們可以反思一個問題:類別是否也是由 “系統” 誕生的?

    其實,我寫這篇文章的目的,並不在給一個所謂的正確答案,所以,光是只得到這個答案:系統,本來就對所謂的物件導向沒啥幫助。

    寫這篇文章的主要目的:軟體人員經常需要自我反思,可以就一個主題(例如本文主題),經常性地提問與思考。真正對軟體人員有幫助的,應該是在這個思考的過程,而並非在於答案的正確與否。

    • 我比較偷懶 乾脆不分他們,我習慣把他們當 工廠或機器,丟什麼東西給他 他會怎麼處理 會回傳什麼。
      比如 我想要完成某件事 我需要一些機器,那我要先想好機器來了要放哪裡?(作用域) 是要用借的(指標) 還是用買的(new) ,機器來了 開一片Employee 的 工作台 取名為 e ,再把 Employee 請進來。
      再來調校 檢查 輸入 =>工作環境變化 => 輸出

  14. 因為在更動態的 OO 語言裡(像 Smalltalk、Ruby),class 也可以是一種 object,class 也可以在 runtime 時修改。

    反之,在動態的 OO 系統裡,object 的生命周期,受 container 掌控的程度遠超出以往的想像(至少是 C++ 時代很難想像的)。

    所以,把 class 和 object 的關係釐清,會讓你更容易善用動態的 OO 系統/語言。

  15. 真正 “誕生” 物件者,其實就是 “系統”!

    請問一下
    一個程式在系統裡面run
    有哪個東西不是”系統””誕生”的?

    這樣的說法對於物件導向的學習有什麼幫助嗎?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *