前言
本文主要來講解一下C#中,自己覺得掌握的不怎麼樣或者用的不多,不太熟悉的關鍵字,主要包括base、this、new、override、abstract、virtual以及針對static字段和static構造函數之間的執行問題。
base關鍵字
base 關鍵字用于在派生類中實作對基類公有或者受保護成員的通路,但是隻局限在構造函數、執行個體方法和執行個體屬性通路器中:
調用基類上已被其他方法重寫的方法。
指定建立派生類執行個體時應調用的基類構造函數。
從靜态方法中使用 base 關鍵字是錯誤的。
this關鍵字
其用于引用類的目前執行個體,也包括繼承而來的方法,通常可以隐藏this:
限定被相似的名稱隐藏的成員
将對象作為參數傳遞到其他方法
聲明索引器
new關鍵字
一、new運算符
1、new一個class時,new完成了以下兩個方面的内容:一是調用new class指令來為執行個體在托管堆中配置設定記憶體;二是調用構造函數來實作對象初始化。
2、new一個struct時,new運算符用于調用其帶構造函數,完成執行個體的初始化。
3、new一個int時,new運算符用于初始化其值為0。
4、 new運算符不可重載。
5、new配置設定記憶體失敗,将引發OutOfMemoryException異常。
二、new修飾符
new 關鍵字可以顯式隐藏從基類繼承的成員。 隐藏繼承的成員時,該成員的派生版本将替換基類版本。 雖然可以在不使用 new 修飾符的情況下隐藏成員,但會生成警告。 如果使
用 new 顯式隐藏成員,則會取消此警告,并記錄要替換為派生版本這一事實。
在子類中用 new 關鍵字修飾 定義的與父類中同名的方法,叫覆寫。 覆寫不會改變父類方法的功能。
當用子類建立父類的時候,如 A c = new B(),覆寫不會改變父類的功能,仍然調用父類功能。(和override有差別,下面進行講解)
三、new 限制
new 限制指定泛型類聲明中的任何類型參數都必須有公共的無參數構造函數。 如果要使用 new 限制,則該類型不能為抽象類型。
當與其他限制一起使用時,new() 限制必須最後指定:
override關鍵字
要擴充或修改繼承的方法、屬性、索引器或事件的抽象實作或虛實作,必須使用 override 修飾符。
由 override 聲明重寫的方法稱為重寫基方法。 重寫的基方法必須與 override 方法具有相同的簽名。
不能重寫非虛方法或靜态方法。 重寫的基方法必須是 virtual、abstract 或 override 的。
用關鍵字 virtual 修飾的方法,叫虛方法。可以在子類中用override 聲明同名的方法,這叫“重寫”。相應的沒有用virtual修飾的方法,我們叫它實方法。 重寫會改變父類方法的功能。
new 和override
1、 不管是重寫還是覆寫都不會影響父類自身的功能。
2、當用子類建立父類的時候,如 A c = new B(),重寫會改變父類的功能,即調用子類的功能;而覆寫不會,仍然調用父類功能。
3、虛方法、實方法都可以被覆寫(new),抽象方法,接口 不可以。
4、抽象方法,接口,标記為virtual的方法可以被重寫(override),實方法不可以。
5、重寫使用的頻率比較高,實作多态;覆寫用的頻率比較低,用于對以前無法修改的類進行繼承的時候。
abstract關鍵字
針對abstract關鍵字暫時總結了以下五點:
1.用關鍵字abstract定義的類即為抽象類,且隻能作為基類,也不能被執行個體化。
2.用abstract定義的類不一定包含抽象方法,也可以包含非抽象方法。
3.abstract定義的方法一定包含在抽象類中。
4.抽象類不能定義為密封類(sealed),抽象方法不能使用virtual、static、private修飾符
5.如果派生類沒有實作所有的抽象方法,則該派生類也必須聲明為抽象類。
virtual關鍵字
Virtual方法(虛方法)
virtual 關鍵字用于在基類中修飾方法。virtual的使用會有兩種情況:
情況1:在基類中定義了virtual方法,但在派生類中沒有重寫該虛方法。那麼在對派生類執行個體的調用中,該虛方法使用的是基類定義的方法。
情況2:在基類中定義了virtual方法,然後在派生類中使用override重寫該方法。那麼在對派生類執行個體的調用中,該虛方法使用的是派生重寫的方法。
static字段和static構造函數
主要來說明執行的順序:
1、編譯器在編譯的時候,先分析所需要的靜态字段,如果這些靜态字段所在的類有靜态的構造函數,那麼就會忽略字段的初始化;如果沒有靜态的構造函數,那麼就會對靜态字段進行初始化。
2、如果存在多個靜态類,那麼初始化的靜态成員的順序會根據引用的順序,先引用到的先進行初始化,但如果類的靜态成員的初始化依賴于其他類的靜态成員,則會先初始化被依賴的靜态成員。
3、而帶有靜态構造函數的類的靜态字段,隻有在引用到的時候才進行初始化。
下面我們來看兩個簡單的小例子:
結果如何呢?再來看第二個小例子:
對比一下,這兩個例子,如果你想的和你執行後的結果一緻,那說明你應該已經明白它們的執行順序了。