冰楓論壇

 找回密碼
 立即註冊
ads_sugarbook
搜索
查看: 1868|回覆: 0
打印 上一主題 下一主題

[心得] [C#] 物件導向 Virtual/Override/Hide 覆寫-隱藏做動規則

[複製鏈接]

620

主題

0

好友

765

積分

高級贊助會員

Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20

UID
390967
帖子
1185
主題
620
精華
0
積分
765
楓幣
6874
威望
308
存款
4100
贊助金額
1800
推廣
0
GP
1622
閱讀權限
150
在線時間
142 小時
註冊時間
2023-5-18
最後登入
2024-4-28

2023年紀念勳章 太陽勳章 神手勳章 高級客戶 VIP會員 私服達人 懶人勳章 幼兒勳章 音樂勳章 屁孩勳章 貢獻王 性別(女) 性別(男) 積分勳章 發帖達人 2023端午節紀念勳章 富豪勳章 富可敵國 2023中秋節紀念勳章 解說達人 論壇粉絲 2023聖誕節紀念勳章

跳轉到指定樓層
1
發表於 2023-6-14 15:51:23 |只看該作者 |倒序瀏覽
本帖最後由 whitefox 於 2023-6-15 17:26 編輯

物件導向中使用虛方法的基本型態是
1. 使用 virtual 修飾詞放在父類別方法宣告前
2. 使用 override 修飾詞放在子類別方法宣告前(或是使用new修飾詞)
覆寫:
  1. public class Vehicle
  2. {
  3.     public virtual void Run()
  4.     {
  5.         Console.WriteLine("Base Class - Vehicle Run!");
  6.     }
  7. }

  8. public class Car : Vehicle
  9. {
  10.     public override void Run()
  11.     {
  12.         Console.WriteLine("Derived Class - Car Run!");
  13.     }
  14. }
複製代碼
主程式:
  1. Vehicle v = new Car();
  2. v.Run();
複製代碼
輸出:『Derived Class - Car Run!』

以下這個不常見,軟體開發中基本不會用,若出現基本上都是錯誤情況才會誤用,這邊做個紀錄
取代掉override改用new隱藏,要用this與base區分使用基礎類別的方法還是該子類別的方法
隱藏:
  1. public class Vehicle
  2. {
  3.     public virtual void Run()
  4.     {
  5.         Console.WriteLine("Base Class - Vehicle Run!");
  6.     }
  7. }

  8. public class Car : Vehicle
  9. {
  10.     public new void Run()
  11.     {
  12.         Console.WriteLine("Derived Class - Car Run!");
  13.     }
  14. }
複製代碼
主程式:
  1. Vehicle v = new Car();
  2. v.Run();
複製代碼
輸出:『Base Class - Vehicle Run!』

以上兩個例子的主程式中,Vehicle是宣告類別,Car是實體類別
具體的虛方法執行檢查流程如下:
  • 當調用一個物件的方法時,系統會直接去檢查這個物件宣告定義的類別,即宣告類別,看所調用的方法是否為虛方法
  • 如果不是虛方法,那麼它就直接執行該方法。而如果有virtual關鍵字,也就是一個虛方法,那麼這個時候它就不會立刻執行該方法,而是轉去檢查物件的實體類別
  • 在這個實體類別裡,他會檢查這個實體類別的定義中是否有重新實現該虛方法(通過override關鍵字),如果是有,它就不會再找了,而馬上執行該實體類別中的這個重新實現的方法。而如果沒有的話,系統就會不停地往上找實體類別的父類別,並對父類別重複剛才在實體類別裡的檢查,直到找到第一個覆寫了該虛方法的父類別為止,然後執行該類別裡覆寫後的方法


用以下這個例子來統整一下這個規則流程
  1. public class A
  2. {
  3.     public virtual void Func() // 注意 virtual, 表示這是一個虛方法
  4.     {
  5.         Console.WriteLine("Class A Func");
  6.     }
  7. }
  8. class B : A // 注意B是從A類別繼承, 所以A是父類別, B是子類別
  9. {
  10.     public override void Func() // 注意 override, 表示重新覆寫虛函數
  11.     {
  12.         Console.WriteLine("Class B Func");
  13.     }
  14. }
  15. class C : B // 注意C是從B類別繼承, 所以B是父類別, C是子類別
  16. {
  17. }
  18. class D : A // 注意D是從A類別繼承, 所以A是父類別, D是子類別
  19. {
  20.     public new void Func() // 注意 new,表示覆蓋父類別裡的同名方法,而不是重新覆寫
  21.     {
  22.         Console.WriteLine("Class D Func");
  23.     }
  24. }
複製代碼
主程式:
  1. A a;         // 定義一個a這個A類別的物件, 這個A就是a的宣告類別
  2. A b;         // 定義一個b這個A類別的物件, 這個A就是b的宣告類別
  3. A c;         // 定義一個c這個A類別的物件, 這個A就是c的宣告類別
  4. A d;         // 定義一個d這個A類別的物件, 這個A就是d的宣告類別

  5. a = new A(); // 實體化a物件, A是a的實體類別
  6. b = new B(); // 實體化b物件, A是b的實體類別
  7. c = new C(); // 實體化c物件, A是c的實體類別
  8. d = new D(); // 實體化d物件, A是d的實體類別

  9. a.Func();
  10. // 執行a.Func
  11. // 1.先檢查宣告類別A
  12. // 2.檢查到是虛方法
  13. // 3.轉去檢查實體類別A,為虛方法本身
  14. // 4.執行實體類別A中的方法
  15. // 5.輸出結果『Class A Func』

  16. b.Func();
  17. // 執行b.Func
  18. // 1. 先檢查宣告類別A
  19. // 2. 檢查到是虛方法
  20. // 3. 轉去檢查實體類別B,有覆寫的
  21. // 4. 執行實體類別B中的方法
  22. // 5. 輸出結果『Class B Func』

  23. c.Func();
  24. // 執行c.Func
  25. // 1. 先檢查宣告類別A
  26. // 2. 檢查到是虛方法
  27. // 3. 轉去檢查實體類別C,無覆寫的
  28. // 4. 轉去檢查類別C的父類別B, 有覆寫的方法
  29. // 5. 執行父類別B中的Func方法
  30. // 6. 輸出結果『Class B Func』

  31. d.Func();
  32. // 執行d.Func
  33. // 1. 先檢查宣告類別A
  34. // 2. 檢查到是虛方法
  35. // 3. 轉去檢查實體類別D,無覆寫的(這個地方要注意了,雖然D裡有實現Func(),但沒有使用override關鍵字,所以不會被認為是覆寫)
  36. // 4. 轉去檢查類別D的父類別A,為虛方法本身
  37. // 5. 執行父類A中的Func方法
  38. // 6. 輸出結果 『Class A Func』

  39. D d1 = new D();
  40. d1.Func();
  41. // 執行D類別裡的Func(),  輸出結果『Class D Func』
複製代碼
[發帖際遇]: whitefox 正確回答議員「陳彥伯」的「肚臍」提問,因而獲得獎勵 1 楓幣 幸運榜 / 衰神榜
已有 1 人評分楓幣 收起 理由
YYYpo + 2 精品文章!

總評分: 楓幣 + 2   查看全部評分

收藏收藏0 推0 噓1


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1骰子
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們職位招聘本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-4-29 05:21

回頂部