- UID
- 390967
- 帖子
- 1592
- 主題
- 821
- 精華
- 0
- 積分
- 854
- 楓幣
- 10961
- 威望
- 395
- 存款
- 10100
- 贊助金額
- 1800
- 推廣
- 0
- GP
- 2677
- 閱讀權限
- 150
- 在線時間
- 189 小時
- 註冊時間
- 2023-5-18
- 最後登入
- 2024-11-21
|
本帖最後由 whitefox 於 2024-9-10 14:19 編輯
物件導向中使用虛方法的基本型態是
1. 使用 virtual 修飾詞放在父類別方法宣告前
2. 使用 override 修飾詞放在子類別方法宣告前(或是使用new修飾詞)
覆寫:- public class Vehicle
- {
- public virtual void Run()
- {
- Console.WriteLine("Base Class - Vehicle Run!");
- }
- }
- public class Car : Vehicle
- {
- public override void Run()
- {
- Console.WriteLine("Derived Class - Car Run!");
- }
- }
複製代碼 主程式:- Vehicle v = new Car();
- v.Run();
複製代碼 輸出:『Derived Class - Car Run!』
以下這個不常見,軟體開發中基本不會用,若出現基本上都是錯誤情況才會誤用,這邊做個紀錄
取代掉override改用new隱藏,要用this與base區分使用基礎類別的方法還是該子類別的方法
隱藏:- public class Vehicle
- {
- public virtual void Run()
- {
- Console.WriteLine("Base Class - Vehicle Run!");
- }
- }
- public class Car : Vehicle
- {
- public new void Run()
- {
- Console.WriteLine("Derived Class - Car Run!");
- }
- }
複製代碼 主程式:- Vehicle v = new Car();
- v.Run();
複製代碼 輸出:『Base Class - Vehicle Run!』
以上兩個例子的主程式中,Vehicle是宣告類別,Car是實體類別
具體的虛方法執行檢查流程如下:
- 當調用一個物件的方法時,系統會直接去檢查這個物件宣告定義的類別,即宣告類別,看所調用的方法是否為虛方法
- 如果不是虛方法,那麼它就直接執行該方法。而如果有virtual關鍵字,也就是一個虛方法,那麼這個時候它就不會立刻執行該方法,而是轉去檢查物件的實體類別
- 在這個實體類別裡,他會檢查這個實體類別的定義中是否有重新實現該虛方法(通過override關鍵字),如果是有,它就不會再找了,而馬上執行該實體類別中的這個重新實現的方法。而如果沒有的話,系統就會不停地往上找實體類別的父類別,並對父類別重複剛才在實體類別裡的檢查,直到找到第一個覆寫了該虛方法的父類別為止,然後執行該類別裡覆寫後的方法
用以下這個例子來統整一下這個規則流程- public class A
- {
- public virtual void Func() // 注意 virtual, 表示這是一個虛方法
- {
- Console.WriteLine("Class A Func");
- }
- }
- class B : A // 注意B是從A類別繼承, 所以A是父類別, B是子類別
- {
- public override void Func() // 注意 override, 表示重新覆寫虛函數
- {
- Console.WriteLine("Class B Func");
- }
- }
- class C : B // 注意C是從B類別繼承, 所以B是父類別, C是子類別
- {
- }
- class D : A // 注意D是從A類別繼承, 所以A是父類別, D是子類別
- {
- public new void Func() // 注意 new,表示覆蓋父類別裡的同名方法,而不是重新覆寫
- {
- Console.WriteLine("Class D Func");
- }
- }
複製代碼 主程式:- A a; // 定義一個a這個A類別的物件, 這個A就是a的宣告類別
- A b; // 定義一個b這個A類別的物件, 這個A就是b的宣告類別
- A c; // 定義一個c這個A類別的物件, 這個A就是c的宣告類別
- A d; // 定義一個d這個A類別的物件, 這個A就是d的宣告類別
- a = new A(); // 實體化a物件, A是a的實體類別
- b = new B(); // 實體化b物件, B是b的實體類別
- c = new C(); // 實體化c物件, C是c的實體類別
- d = new D(); // 實體化d物件, D是d的實體類別
- a.Func();
- // 執行a.Func
- // 1.先檢查宣告類別A
- // 2.檢查到是虛方法
- // 3.轉去檢查實體類別A,為虛方法本身
- // 4.執行實體類別A中的方法
- // 5.輸出結果『Class A Func』
- b.Func();
- // 執行b.Func
- // 1. 先檢查宣告類別A
- // 2. 檢查到是虛方法
- // 3. 轉去檢查實體類別B,有覆寫的
- // 4. 執行實體類別B中的方法
- // 5. 輸出結果『Class B Func』
- c.Func();
- // 執行c.Func
- // 1. 先檢查宣告類別A
- // 2. 檢查到是虛方法
- // 3. 轉去檢查實體類別C,無覆寫的
- // 4. 轉去檢查類別C的父類別B, 有覆寫的方法
- // 5. 執行父類別B中的Func方法
- // 6. 輸出結果『Class B Func』
- d.Func();
- // 執行d.Func
- // 1. 先檢查宣告類別A
- // 2. 檢查到是虛方法
- // 3. 轉去檢查實體類別D,無覆寫的(這個地方要注意了,雖然D裡有實現Func(),但沒有使用override關鍵字,所以不會被認為是覆寫)
- // 4. 轉去檢查類別D的父類別A,為虛方法本身
- // 5. 執行父類A中的Func方法
- // 6. 輸出結果 『Class A Func』
- D d1 = new D();
- d1.Func();
- // 執行D類別裡的Func(), 輸出結果『Class D Func』
複製代碼 |
-
總評分: 楓幣 + 2
查看全部評分
|