C 基礎概念 虛方法virtual

2022-09-09 22:27:31 字數 3157 閱讀 6307

在c#中,虛方法就是可以被子類重寫的方法,如果子類重寫了虛方法,則在執行時將執行重寫的邏輯;如果子類沒有重寫虛方法,則在執行時將執行父類的邏輯。虛函式在編譯期間是不被靜態編譯的,它的相對位址是不確定的,它會根據執行時期物件例項來動態判斷要呼叫的函式,其中那個申明時定義的類叫申明類,那個執行時例項化的類叫例項類。虛方法是用virtual關鍵字宣告的

a a = new b(); 其中a是申明類,b是例項類。

虛方法前不允許有static,abstract,或override修飾符(因為靜態的方法和抽象方法不能重寫)

虛方法不能是私有的(因為在子類中要進行重寫),所以不能使用private修飾符

不能在宣告虛方法的同時指定重寫虛方法,因為重寫方法只能重寫基類的虛方法,也就是要提前在基類中宣告虛方法,所以virtual關鍵字和override關鍵字不能同時使用。

允許派生類(即其子類)對父類進行擴充套件。

虛方法是多型特性的一種體現。

增加開發過程中的可維護性,條理清晰明了。

在父類中:12

34public virtual 返回型別 方法名()

在子類中:12

345public override 返回值型別 方法名()

一般方法在編譯時就靜態地編譯到了執行檔案中,其相對位址在程式執行期間是不發生變化的,也就是寫死了的!

虛函式在編譯期間是不被靜態編譯的,它的相對位址是不確定的,它會根據執行時期物件例項來動態判斷要呼叫的函式。

具體的檢查流程如下:

當呼叫乙個物件的方法時,系統會直接去檢查這個物件申明定義的類,即申明類,看所呼叫的方法是否為虛方法。

如果不是虛函式,那麼它就直接執行該函式。如果有virtual關鍵字,也就是乙個虛方法,那麼這個時候它就不會立刻執行該函式了,而是轉去檢查物件的例項類。

在這個例項類裡,它會檢查這個例項類的定義中是否有實現該虛方法(通過new關鍵字)或是否有重新實現該虛方法(通過override關鍵字),如果有,那麼ok,它就不會再找了,而馬上執行該例項類中的這個重新實現的方法。而如果沒有的話,系統就會不停地往上找例項類的父類,並對父類重複剛才在例項類裡的檢查,直到找到第乙個過載了該虛方法的父類為止,然後執行該父類裡過載後的方法。

下面我們通過具體例項看看:

例1:123

4567

891011

1213

1415

16class a

}class program

}過程:1.先檢查申明類a 2.檢查到是getreturn是虛擬方法 3.轉去檢查例項類a,結果是它本身 4.執行例項類a中實現getreturn的方法 5.輸出結果我是a類的虛方法

例2:123

4567

891011

1213

1415

1617

1819

2021

2223

class a

}class b : a

}class program

}過程:1.先檢查申明類a 2.檢查到是虛擬方法 3.轉去檢查例項類b,有重寫的方法 4.執行例項類b中的方法 5.輸出結果我是b類重寫後的方法

例3:123

4567

891011

1213

1415

1617

1819

2021

2223

2425

2627

class a

}class b : a

}class c : b

class program

}過程:1.先檢查申明類a 2.檢查到是虛擬方法 3.轉去檢查例項類c,無重寫的方法 4.轉去檢查類c的父類b,有重寫的方法5.執行父類b中的getreturn方法 6.輸出結果我是b類重寫後的方法

例4:123

4567

891011

1213

1415

1617

1819

2021

2223

class a

}class b : a

}class program

}過程:1.先檢查申明類a 2.檢查到是虛擬方法

3.轉去檢查例項類b,無重寫的(這個地方要注意了,雖然b裡有實現getreturn(),但沒有使用override關鍵字,所以不會被認為是重寫)

4.轉去檢查類b的父類a,就是它本身 5.執行父類a中的getreturn方法 6.輸出結果我是a類的虛方法

例5:123

4567

891011

1213

1415

1617

1819

2021

2223

class a

}class b : a

}class program

}過程:1.先檢查申明類b 2.檢查到不是虛擬方法 3.執行b類裡的getreturn() 4.輸出結果我是b類new方法

可以使用抽象方法重寫基類中的虛方法12

3456

78910

1112

1314

15class a  }

abstract class b : a    

abstract class c : a

密封類可以重寫基類中的虛方法(基類中的虛方法將隱式的轉化為非虛方法,但密封類本身不能再增加新的虛方法)12

3456

78910

1112

1314

1516

1718

1920

class a

}sealed class program:a

static void main(string args)

}虛方法和new

new關鍵用於隱藏父類的成員,所有可以用new關鍵字隱藏父類的虛擬方法。

abstract和虛擬方法

抽象方法是隱式的虛擬方法,所有抽象類的非抽象子類可以用new 和override關鍵來重寫abstract 方法

C 中虛方法 virtual 詳解

前言 在前面的部落格重寫中提到了虛方法和抽象類,本博文詳細介紹下虛方法 當有乙個定義在類中的函式需要在繼承類中實現時,可以使用虛方法,虛方法是使用關鍵字virtual宣告的,虛方法可以在不同的繼承類中有不同的實現,即為基類中定義的允許在派生類中重寫的方法 一般的宣告形式如下 訪問修飾符 virtua...

虛方法virtual詳解

從c 的程式編譯的角度來看,它和其它一般的函式有什麼區別呢?一般函式在編譯時就靜態地編譯到了執行檔案中,其相對位址在程式執行期間是不發生變化的,也就是寫死了的!而虛函式在編譯期間是不被靜態編譯的,它的相對位址是不確定的,它會根據執行時期物件例項來動態判斷要呼叫的函式,其中那個申明時定義的類叫申明類,...

C 虛函式 virtual

定義虛函式 為了指明函式為虛函式,在其返回型別前面加上保留字virtual,目的是啟用動態繫結。繼承層次的根類一般都要定義虛析構函式。成員預設為非虛函式,對非虛函式的呼叫在編譯時確定。除建構函式外,任意非static成員函式都可以是虛函式。保留字virtual只在類內部的成員函式宣告 現,不能用在類...