2009年12月23日

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

http://blog.miniasp.com/post/2009/08/OOP-Basis-What-is-class-and-object.aspx http://blog.miniasp.com/post/2009/10/OOP-Basis-What-is-class-and-object-ANSWER.aspx 含糊帶過
  • 類別:就是 class 啊~ ( 這…我不是請你來翻譯的 )
  • 物件:物件不就是可以 new 的那種嗎? ( 對,但這樣回答不太好吧… )

簡單帶過

  • 類別:定義程式的方法、屬性
  • 物件:可執行的東西

裝死

  • 類別:我不知道 ( 可能是沒自信說出來或真的不知道? ) <= 最糟糕的答案!
  • 物件:我不知道 ( 可能是沒自信說出來或真的不知道? ) <= 最糟糕的答案!

我知道程式設計的領域有許多抽象概念,很多東西無法清楚的「直接」描述,所以要瞭解抽象概念就需要透過「比喻」來描述才比較能讓人瞭解,所以我建議那些講不出抽象概念的人要多學著用「比喻」的方式講解抽象概念,你能將抽象概念描述的越具體,相對的你對技術的掌握也越精準。

我個人所學到大部分的程式技能都是透過自修而來的,過程中經常沒人帶領,甚至找不到人可問,除了靠自身的興趣與熱情外,還需要靠大量的時間去消化、去理解、去求證,過程可說十分痛苦,但熱情如同嗎啡一般,確實可以減低許多自我成長時的痛苦感。

程式菜鳥在學習抽象概念時經常一知半解,若自己不求甚解的話久而久之真的會變成半弔子,變成只會寫 Code 的人(Coder),而不是 Programming 的人(Programmer),不但未來的路途變窄了,寫程式也會缺乏很多創意,沒有創意也就沒有熱情了。

首先聲明

  • 我不是什麼學者,講不出課本要的正確答案,想知道正確答案請查閱物件導向相關書籍。
  • 如果你問 100 個人這個問題,可能會得到 200 個答案,所以你一定要有自己獨到、有自信、精闢的見解或描述方式。

★ 我的個人見解:

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

簡單解釋:

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

比喻一:建築物

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

比喻二:蓋世武功

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

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

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

  1. 請問「類別」可不可以包含「物件」?
  2. 請問「物件」可不可以包含「類別」?
  3. 請問「類別」可不可以包含「類別」?
  4. 請問「物件」可不可以包含「物件」?
  5. 請問「物件」可不可以當成資料傳遞?
  6. 請問「類別」可不可以當成資料傳遞?
  7. 在 .NET 的世界,請問「物件」可以用什麼型態存在或用什麼格式傳遞?(可任意回答一種以上)
  8. 在 .NET 的世界,請問「類別」可以用什麼型態存在或用什麼格式傳遞?(可任意回答一種以上)
  9. 在 .NET 的世界,程式在執行的時候,「類別」可不可以被動態修改?
  10. 如果有兩台主機要互相傳遞資料,他們傳遞的是「類別」還是「物件」?
  11. 請問「物件」是否包含「方法(Method)」?
  12. 如果「物件」從 A 電腦傳遞到 B 電腦時,若該物件要執行「方法」還需不需要有「類別」存在?

這些問題每個人看的時候理解可能不同,甚至於可能覺得題目有問題(模稜兩可或題目不合邏輯或錯誤),若覺得題目有問題在回答時需明確說明哪裡有問題。所以每個人的答案也許也很不一樣,你們就用自己的理解來回答即可,不用害怕答錯。

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 本題解答:
    • 原生資料 ( 記憶體區塊, Has )
    1. 序列化資料 ( 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 電腦是需要有「類別」存在的。
  • 本題解答:「需要

-----

說實在的,這種物件基礎的問題我不知道多少人認真思考過,而且有多少人不瞭解這些觀念程式一樣寫的嚇嚇叫,如安德魯所說的:「平常都沒什麼人可以跟我討論這類問題」,我也是感同身受。

如 果有人能帶領學習物件導向觀念真的學比較快,但又有多少人有機會遇到這樣的學習環境呢,我自己的程式生崖一路走來也是濛濛懂懂、跌跌撞撞的,之前都在寫 PHP, Perl 都不是很純的物件導向程式語言,直到深入研究 .NET 才能體會一些物件導向的抽象概念,我大部分觀念也是從書裡學來的,然後再從自己寫過的程式去反覆驗證,最後就會得到一個很清晰的物件導向觀念。

沒有留言: