C#中的虛方法(virtual)例項講解
虛擬函式從C#的程式編譯的角度來看,它和其它一般的函式有什麼區別呢?一般函式在編譯時就靜態地編譯到了執行檔案中,其相對地址在程式執行期間是不發生變化的,也就是寫死了的!而虛擬函式在編譯期間是不被靜態編譯的,它的相對地址是不確定的,它會根據執行時期物件例項來動態判斷要呼叫的函式,其中那個申明時定義的類叫申明類,那個執行時例項化的類叫例項類。
比如:
User u=new Teacher();
那麼User就是宣告類,Teacher就是例項類。
#具體的檢查的流程如下:
1、當呼叫一個物件的函式時,系統會直接去檢查這個物件申明定義的類,即申明類,看所呼叫的函式是否為虛擬函式;
2、如果不是虛擬函式,那麼它就直接執行該函式。而如果有virtual關鍵字,也就是一個虛擬函式,那麼這個時候它就不會立刻執行該函式了,而是轉去檢查物件的例項類。
3、在這個例項類裡,他會檢查這個例項類的定義中是否有重新實現該虛擬函式(通過override關鍵字),如果是有,它就不會再找了,而馬上執行該例項類中的這個重新實現的函式。而如果沒有的話,系統就會不停地往上找例項類的父類,並對父類重複剛才在例項類裡的檢查,直到找到第一個過載了該虛擬函式的父類為止,然後執行該父類裡過載後的函式。
#程式碼例項:
namespace VirtualTest
{
class A
{
public virtual void Func()
{
Console.WriteLine("Func In A");
}
}
class AB : A
{
public override void Func() // 注意override ,表明重新實現了虛擬函式
{
Console.WriteLine("Func In AB");
}
}
class BC : B
{
}
class AD : A
{
public new void Func() // 注意new ,表明覆蓋父類裡的同名類,而不是重新實現
{
Console.WriteLine("Func In AD");
}
}
class program
{
static void Main()
{
A a; // 定義一個A類的物件a.這個A就是a的申明類
A b; // 定義一個A類的物件b.這個A就是b的申明類
A c; // 定義一個A類的物件c.這個A就是c的申明類
A d; // 定義一個A類的物件d.這個A就是d的申明類
a = new A(); // 例項化a物件,A是a的例項類
b = new AB(); // 例項化b物件,AB是b的例項類
c = new BC(); // 例項化c物件,BC是c的例項類
d = new AD(); // 例項化d物件,AD是d的例項類
a.Func(); // 執行a.Func:1.先檢查申明類A 2.檢查到是虛擬方法 3.轉去檢查例項類A,就為本身 4.執行例項類A中的方法 5.輸出結果 Func In A
b.Func(); // 執行b.Func:1.先檢查申明類A 2.檢查到是虛擬方法 3.轉去檢查例項類AB,有過載的 4.執行例項類AB中的方法 5.輸出結果 Func In AB
c.Func(); // 執行c.Func:1.先檢查申明類A 2.檢查到是虛擬方法 3.轉去檢查例項類BC,無過載的 4.轉去檢查類BC的父類AB,有過載的 5.執行父類AB中的Func方法 5.輸出結果 Func In AB
d.Func(); // 執行d.Func:1.先檢查申明類A 2.檢查到是虛擬方法 3.轉去檢查例項類AD,無過載的(這個地方要注意了,雖然D裡有實現Func(),但沒有使用override關鍵字,所以不會被認為是過載) 4.轉去檢查類D的父類A,就為本身 5.執行父類A中的Func方法 5.輸出結果 Func In A
AD ad1 = new AD();
ad1.Func(); // 執行D類裡的Func(),輸出結果 Func In AD
Console.ReadLine();
}
}
}
例項的輸出結果為:
Func In A
Func In AB
Func In AB
Func In A
Func In AD
相關文章
- C# StartsWith 字串的例項方法解析C#字串
- SQL觸發器例項講解SQL觸發器
- C#中抽象方法與虛方法的區別詳解及示例C#抽象
- Java虛擬機器中獲得Runtime例項的方法是什麼?Java虛擬機
- Python裝飾器例項講解(三)Python
- 防抖和節流(例項講解)
- Unity射擊例項講解—主角建立Unity
- python例項方法中self的作用Python
- C# 中 釋出訂閱例項C#
- php例項化物件的例項方法PHP物件
- 例項講解hadoop中的map/reduce查詢(python語言實現HadoopPython
- Vue.js 2.0中$on與$emit如何使用之例項講解Vue.jsMIT
- Vmware fusion virtual machine nogui無介面啟動管理虛擬機器例項便捷指令碼MacGUI虛擬機指令碼
- C#並行,多執行緒程式設計並行集合和PLINQ的例項講解並行執行緒程式設計
- 設計模式 - 原則及例項講解設計模式
- 設計模式例項講解 - 里氏替換設計模式
- 設計模式例項講解 - 介面隔離設計模式
- 設計模式例項講解 - 依賴倒置設計模式
- Unity射擊例項講解—子彈建立Unity
- Android:Retrofit 2.0 使用攻略(含例項講解)Android
- 例項講解虛擬機器3種網路模式(橋接、nat、Host-only)虛擬機模式橋接
- C#雜湊表的例項C#
- C# IDispose使用例項C#
- 例項講解:我的強化學習初體驗!強化學習
- Macro / Micro / Weighted AUC 如何計算例項講解Mac
- 設計模式例項講解 - 開放封閉設計模式
- Android探索之旅 | AIDL原理和例項講解AndroidAI
- Retrofit2與服務端例項講解服務端
- 掌握C#中的GUI多執行緒技巧:WinForms和WPF例項詳解C#GUI執行緒ORM
- C#中WebService的建立、部署和呼叫的簡單例項C#Web單例
- python中time庫的例項使用方法Python
- c#中單例模式詳解C#單例模式
- Js 的事件迴圈(Event Loop)機制以及例項講解JS事件OOP
- 對pandas進行資料預處理的例項講解
- C#開發例項大全C#
- Vue 原始碼解讀(6)—— 例項方法Vue原始碼
- 一個例項中,多個synchronized方法的呼叫synchronized
- java中String類常用方法的使用與例項Java