冰楓論壇

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

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

[複製鏈接]

1114

主題

0

好友

1042

積分

高級贊助會員

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

UID
390967
帖子
2182
主題
1114
精華
0
積分
1042
楓幣
26484
威望
578
存款
10100
贊助金額
1800
推廣
0
GP
3799
閱讀權限
150
在線時間
272 小時
註冊時間
2023-5-18
最後登入
2025-12-25

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

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

物件導向中使用虛方法的基本型態是
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物件, B是b的實體類別
  7. c = new C(); // 實體化c物件, C是c的實體類別
  8. d = new D(); // 實體化d物件, D是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鑰匙
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$

0

主題

0

好友

0

積分

新手上路

Rank: 1

UID
497934
帖子
18
主題
0
精華
0
積分
0
楓幣
22
威望
0
存款
0
贊助金額
0
推廣
0
GP
0
閱讀權限
10
性別
保密
在線時間
2 小時
註冊時間
2025-11-18
最後登入
2025-12-10
2
發表於 2025-12-10 05:15:14 |只看該作者
「貨出得去,人進得來,高雄發大財」
[發帖際遇]: odasm 身為「IT高手」,協助「嫦蓉」公司揪出「紙菸」加料事件,獲得獎勵 2 楓幣 幸運榜 / 衰神榜
點評回覆

使用道具 舉報

高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們管群招募本站規範DMCA隱私權政策詐騙防範及資料調閱

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

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

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

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

GMT+8, 2025-12-26 02:14

回頂部