看板 C_Sharp 關於我們 聯絡資訊
各位學長好 我在看深入淺出C#的時候有一個疑問 第一版(買的時候沒注意...) P267、P268的部分有談到向上、向下轉型 就我個人的理解 例如父類有A方法,子類有B、C方法 向上轉型: 將子類別的物件內容等同於父類 父類名 物件1 = new 子類名(); 原本子類物件可以使用A、B、C方法 向上轉型後的物件1就只能使用父類的A方法 向下轉型: 將向上轉型的物件,用一個新物件再轉回來 上面的子類物件現在只能用A方法 那我再用一個物件讓他轉回來(???) 子類名 物件2 = 物件1 as 子類名; 這樣物件2就能使用A、B、C三種方法 在這裡我就有問題了 為什麼要這樣向上向下轉型? 如果直接new一個新的父類物件 效果不就等同向上轉型後的物件嗎? 如果直接new一個新的子類物件 效果不就等同向下轉型後的物件嗎? 有什麼情況非得要用向上、向下轉型不可呢? 請各位學長不吝指教,感謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.125.120.238 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_Sharp/M.1574328676.A.449.html
s4300026: 不,你搞錯了,真相只有一個,就是實體只有一個。其他 11/21 18:21
s4300026: 都是標籤紙,is是判斷能不能把標籤貼在實體上,as是回 11/21 18:21
s4300026: 傳一個已經貼在上面,並且標籤名稱是你指定的。 11/21 18:21
s4300026: 實體就是你new出來的東西,new回傳的東西也是標籤紙。 11/21 18:26
s4300026: 然後第三句話,標籤名稱要改成標籤型態。 11/21 18:27
感謝S大的標籤紙說明讓我多了些想法 我又再研究了一下: 父類別 物件1 = new 子類別(); 這樣會產生一個名為 物件1 實體 之後再 子類別 物件2 = 物件1 as 子類別; 在這裡 物件2 其實就是 物件1 只是貼上了 物件2 的標籤 於是就產生出和 物件1 相同內容的 物件2 但差別 物件2 可以使用子類別方法 因為他已經被貼上子類的標籤 同時,如果用 物件2 去改變子類的屬性時 物件1 也會受到影響,因為是同一個實體 這樣的理解正確嗎?
s4300026: ================= 11/21 18:31
s4300026: 那為什麼要向上轉型,因為你很懶,當你有一堆子類別時, 11/21 18:40
s4300026: 你不想要宣告一堆變數去記住實體在哪,父類別都可接, 11/21 18:40
s4300026: 還可以直接用爸爸的方法,當你真的要用兒子的方法時,再 11/21 18:40
s4300026: 向下轉型就好了。 11/21 18:40
berice152233: 感謝,有點複雜,我會努力理解的 11/21 22:45
samchung: 推s大的標籤紙形容 XD 11/21 23:18
samchung: 小弟想到物件集合(或物件陣列)的應用情況 11/22 00:33
samchung: 請參考範例 https://dotnetfiddle.net/KNvWy4 11/22 00:33
samchung: 關鍵在泛型集合使用父類別的型別 11/22 00:34
samchung: 才可在集合內放入相同血緣關係的父、子物件 11/22 00:34
Litfal: 標籤紙讚讚 至於為什麼要轉, 得從OOAD最基本的收納與使用 11/22 09:15
感謝各位學長的回答 大概是因為我還沒開始寫很長的程式 所以還搞不太懂上下轉型的重要性 目前看起來是要節省寫程式時的麻煩 還有增加閱讀性? ※ 編輯: berice152233 (59.125.120.238 臺灣), 11/22/2019 10:08:47
Litfal: 來想。你有一些鉛筆和一個鉛筆盒,鉛筆盒只能放鉛筆,那你 11/22 09:22
Litfal: 拿到原子筆時就會有點麻煩。你有兩個選擇:1.做一個原子 11/22 09:22
Litfal: 筆盒拿來放原子筆。2.把鉛筆和原子筆都視為筆,並把鉛筆和 11/22 09:23
Litfal: 改成筆盒,可以放所有種類的筆。 盒 11/22 09:23
Litfal: 想當然是2.比較好,你也不想包包裡塞滿各種類的筆盒吧? 11/22 09:27
Litfal: 而且未來有其他種類的筆,也是直接塞進筆盒裡就好。 11/22 09:28
Litfal: 這是收納部分。而使用上,管他什麼筆,都可以用來寫 11/22 09:31
Litfal: 所以會在父項 筆 的類別裡面,定義 寫() 的方法 11/22 09:33
Litfal: 你從筆盒裡面拿出的筆,管它是什麼筆,拿出來就可以寫() 11/22 09:33
Litfal: 至於各種筆自己獨特的功能,例如多色筆可以換色,自動筆可 11/22 09:36
Litfal: 以換筆芯,鉛筆可以被削,這些功能就由子類別個別去實作 11/22 09:36
Litfal: 向下轉型的需求就由此而來。例如你有台削鉛筆機,它只吃鉛 11/22 09:40
Litfal: 筆。原本隨便從鉛筆盒拿出一支筆都能削,現在,你必須檢查 11/22 09:42
Litfal: (或是由削鉛筆機檢查)你從筆盒拿出的筆,它是不是鉛筆, 11/22 09:42
Litfal: 確定是鉛筆後才能把它塞給削鉛筆機來削 11/22 09:42
感謝L大的說明,這個例子也很好懂 稍微能對as的應用有具體的想像了 ※ 編輯: berice152233 (59.125.120.238 臺灣), 11/22/2019 10:12:08
s4300026: 實際上標籤紙的概念是出於 深入淺出 C#,也就是你正在 11/22 10:55
s4300026: 讀的那本,那本書上的圓圈就是實體,方框內的名稱就是 11/22 10:55
s4300026: 標籤。 XD 11/22 10:55
對,我也是看了你的說明之後往前翻 就有種恍然大悟的感覺,哈哈
s4300026: 實際上,在實務上只有強調轉型,我們並不在乎是 “向上 11/22 10:55
s4300026: 還是向下轉型”,在後面的章節,interface的關鍵字,你 11/22 10:55
s4300026: 就會體會到了。 11/22 10:55
那我就期待看到這邊了 ※ 編輯: berice152233 (59.125.120.238 臺灣), 11/22/2019 11:15:53
s4300026: 回頭看了你的敘述,在你的回覆中,“於是就產生出和 物 11/24 09:36
s4300026: 件1 相同內容的 物件2”,這段敘述是錯誤的,所謂的 “ 11/24 09:37
s4300026: 產生”,就是new,這是錯誤的理解。 11/24 09:37
s4300026: 正確的理解是:Parent A = new Son(); //產生一個子類別 11/24 09:40
s4300026: 實體,然後把父類別標籤貼上去 11/24 09:40
s4300026: 標籤名稱為 A。 if(A is Son) Son B = A as Son。 如果: 11/24 09:54
s4300026: 標籤A所貼的實體 可以被當成 子類別,則:標籤A所貼的實 11/24 09:54
s4300026: 體 請把他當成 子類別 看待,然後我把 子類別 的標籤貼 11/24 09:54
s4300026: 上去,標籤名為B。 11/24 09:54
s4300026: A = new Parent(); 然後,我把標籤紙A “改貼在” 新的 11/24 09:59
s4300026: 父類別實體上。 11/24 09:59
阿...原來是貼上父類標籤的子類實體 經你這麼一說我對於實體的概念不太明確 感謝解說 ※ 編輯: berice152233 (59.125.120.238 臺灣), 11/26/2019 13:19:06
nickboy: 我基本上都用向下居多,向上是懶惰的時候才會用 12/06 17:07