2011年8月18日 星期四

轉貼 物件導向基礎:何謂類別(Class)?何謂物件(Object)?

http://www.kenming.idv.tw/c_carp_object_c_aofaofa_m_ei_a_y_class_i

類別" 這個主題,絕對是在物件導向觀念中,最為關鍵的核心,因為,決定資訊系統因應需求變動而所能承受的震盪程度,取決於類別圖的設計,真正的軟體行家,如 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"。


http://blog.miniasp.com/post/2009/08/27/OOP-Basis-What-is-class-and-object.aspx

類別(Class) 與 物件(Object) 是個一體兩面的東西,以下我用幾個不同的方式說明這兩著的差別:

簡單解釋:

類別算是一個藍圖、一個範本、一個可參考的文件,他沒有實體 (Instance),屬靜態的。
物件是一個看的到、摸的到的實體,屬於動態的,狀態會隨時改變,但架構與行為不會改變。

比喻一:建築物

類別:設計藍圖
物件:實際蓋好的房子
兩者關係:設計藍圖(類別)決定房子應該怎麼蓋,決定幾台電梯、幾間房間、走道如何設計。實際蓋好的房子(物件)是照著設計藍圖所蓋出來的房子,人只能照設計藍圖的設計使用這間房子。

比喻二:蓋世武功

類別:武林密笈
物件:修練武林密笈而成的武林高手
兩者關係:武林密笈(類別)記載許多各種攻擊與回應的方式,讓武林高手(物件)知道遭遇到什麼攻擊時要用什麼招式回應。
程式設計:每執行到我們用 new 運算子時,等同於將物件產生,也等同於成功得到武林密笈可以開始練功,或是在「建構子」的時候就已經賦予你基本功力。

基本上,類別只用來決定物件形成時的樣子,當物件形成時,物件就變成一個記憶體中的空間,記載著物件活動時暫存的資料與狀態,並且當有類別存在時有能力透過方法(Method)執行一些動作。

以下幾個基本的考題考考各位,看有沒有人可以回答出正確答案:

1. 請問「類別」可不可以包含「物件」?

基本上「類別」為「虛」,而「物件」屬「實」
「類別」與「物件」兩者之間應該要有個清楚的界線,不應該混為一談。
我個人認為即便是「靜態欄位」或「靜態方法」都不能算是「物件」,在物件導向的領域應該還是算類別中的「定義」而已,這些「靜態欄位」是在類別被載入 應用程式域(AppDomain) 時才變成物件的,而且靜態欄位所屬物件不需要 new 就會先佔用固定的一份記憶體空間,所以載入過多的靜態類別對應用程式來說也是一種負擔,這一點可能很多人不知道 (現在記憶體實在太大了)。
本題解答:「本題無解」或「不可以」

2. 請問「物件」可不可以包含「類別」?

同上題解釋。
本題解答:「本題無解」或「不可以」

3. 請問「類別」可不可以包含「類別」?

巢狀類別定義就是「類別」包含「類別」的例子。
本題解答:「可以」

4. 請問「物件」可不可以包含「物件」?

在純物件導向的世界裡執行時所有東西都是物件,所以「物件」裡當然可以包含「物件」。
本題解答:「可以」

5. 請問「物件」可不可以當成資料傳遞?

「物件」包含一系列的「狀態」或「資料」,要傳遞物件時必須先透過「序列化技術」將原生資料轉成可傳遞的序列化資料,然後才能當成資料傳遞。
本題解答:「可以」或「不可以,除非先將物件序列化後才能當成資料傳遞」

6. 請問「類別」可不可以當成資料傳遞?

「類別」與「物件」兩者之間應該要有個清楚的界線,不應該混為一談。
提到「資料」的時候,就不應該跟「類別」扯上關係,因為「類別」只是「定義」,「資料」是存在「物件」中的。
除非你把類別原始碼也當成「資料」來看,那就算「可以」,不過這是看法角度的問題,不算正解。
本題解答:「不可以」

7. 在 .NET 的世界,請問「物件」可以用什麼型態存在或用什麼格式傳遞?(可任意回答一種以上)

本題解答:
原生資料 ( 記憶體區塊 )
序列化資料 ( XML, Binary, 自訂格式, … )

8. 在 .NET 的世界,請問「類別」可以用什麼型態存在或用什麼格式傳遞?(可任意回答一種以上)

本題解答:
組件檔案 (Assembly File) ( *.dll , *.exe )
原始碼檔案 ( Class File ) ( *.cs )

9. 在 .NET 的世界,程式在執行的時候,「類別」可不可以被動態修改?

雖然 .NET 支援動態編譯 (CodeDom) 可透過寫程式的方式動態撰寫或定義「類別」並即時編譯/載入目前的應用程式域(AppDomain),但是被定義過的類別是無法修改的,只能將組件卸載後重新載入新的組件或重新編譯修改過的類別。
你試想如果被定義過的類別可以動態被修改的話,那麼 .NET 病毒可能已經滿天飛了。
本題解答:「不可以」

10. 如果有兩台主機要互相傳遞資料,他們傳遞的是「類別」還是「物件」?

「類別」與「物件」兩者之間應該要有個清楚的界線,不應該混為一談。
在傳遞「資料」的時候,資料本身即便是 字串(String) 也是個物件。
本題解答:「物件」

11. 請問「物件」是否包含「方法(Method)」?

「方法(Method)」屬於一種「定義」,他是「類別」的一部分,並非物件。
當物件要執行特定方法時,事實上去參考「類別」中定義的方法,並執行。
本題解答:「不包含」

12. 如果「物件」從 A 電腦傳遞到 B 電腦時,若該物件要執行「方法」還需不需要有「類別」存在?

「物件」包含一系列的「狀態」或稱「資料」,要傳遞物件時必須先透過「序列化技術」將原生資料轉成可傳遞的序列化資料,然後才能傳遞到另一台電腦。
「類別」是一種定義、一種參考,所以當 B 電腦得到 A 電腦傳來的資料時,對 B 電腦來說收到的僅僅是一串「資料」罷了,並非物件,若 B 電腦沒有「類別」定義的存在,便無法將這些「資料」給「反序列化」成「物件」,所以 B 電腦是需要有「類別」存在的。
本題解答:「需要」

沒有留言: