1、虛方法:把一個基類函數聲明為 virtual,就可以在任何派生類中重寫該函數。
2、在Java 中所有函數都是虛擬的,但是在C# 中,C# 要求在派生類的函數重寫另一個函數時,要使用 override 關鍵字顯式聲明。
//父類 class MyBaseClass{ public virtual string VirtualMethod(){ return "This is test!"; } } //派生類 class MyDerivedClass:MyBaseClass{ public override string VirtualMethod(){ return "Haha, I override you." } }
3、成員字段和靜態函數都不能聲明為 virtual ,因為這個概念只對類中的實例函數成員有意義。
4、隱藏方法:如果簽名相同的方法在基類和派生類中都進行了聲明,但該方法沒有分別聲明為 virtual 和 override ,派生類的方法就會隱藏基類方法。在大多數情況下,是要重寫方法,而不是隱藏方法,因為隱藏方法會造成對於給定類的實例調用錯誤方法的危險。在c#中,要隱藏一個方法,應該使用 new 關鍵字聲明。
class MyDerivedClass:MyBaseClass{ public new string VirtualMethod(){ //... return 0; } }
5、調用函數的基類版本 : base . <MethodName>()
class MyBaseClass{ public virtual string getName(){ return "Hello ,Robert!"; } } class MySonClass : MyBaseClass{ public override string getName(){ return base.getName(); } }
6、【專題】抽象類和抽象函數。(abstract)
抽象類:
抽象函數:
7、密封類和密封方法。 sealed
對於類:表示不能繼承該類。
對於方法:表示不能重寫該方法。
string 為密封類。
要在方法或屬性上使用 sealed 關鍵字,必須先從基類上把它聲明為要重寫的方法或屬性。如果基類上不希望有重寫的方法或屬性,就不要把它聲明為 virtual。
8、【派生類中的構造函數執行過程】
abstract class GenericCustomer{ private string name; } class NevermoreCustomer:GenericCustomer{ private uint highCostMinutesUsed; } GenericCustomer customer=new NevermoreCustomer();
【執行過程】:編譯器首先找到它試圖實例化的類的構造函數,在本例中是 NevermoreCustomer ,這個默認 NevermoreCustomer 構造函數首先要做的是為其直接基類 GenericCustomer 運行默認構造函數,然後GenericCustomer 構造函數為其直接基類System.Object 運行默認構造函數,System.Object 沒有任何基類,所以它的構造函數就執行,並把控制權返回給GenericCustomer 構造函數,現在執行 GenericCustomer 構造函數, 把變量 name 初始化 為 null 。再把控制權返回給 NevermoreCustomer 構造函數, 接著執行這個構造函數, 把 highCostMinuteUsed 初始化為 0 並退出。
構造函數的調用順序是先調用 System.Object, 再按照層次結構由上向下進行。直到達到編譯器要實例化的類為止。
9、this 和 base
this 為調用當前類中的其他構造方法。
base 在派生類中使用時,調用基類中的構造方法。
10、接口 。Microsoft 預定義的一個接口 System.IDisposable。 它包含一個方法 Dispose() ,該方法由類實現,用於清理代碼。
1 public interface Idisposable{ 2 void Dispose(); 3 }
接口在語法上與聲明抽象類完全相同,但不允許提供接口中任何成員的實現方式。一般情況下,接口只能包含方法,屬性,索引器和事件的聲明。不能實例化接口,它只能包含其成員的簽名。接口既不能有構造函數,也不能有字段。接口定義也不允許包含運算符重載,不允許聲明關於成員的修飾符。接口成員總是共有的,不能聲明為虛擬或靜態。
11、【專題 C#中抽象類和接口的區別】
Ⅰ、抽象類
① 抽象類是特殊的類,只是不能被實例化。除此之外,具有類的其他特性。
② 抽象類可以包含抽象方法,這是普通類所不能的。
③ 抽象方法只能聲明於抽象類中,且不包含任何實現,派生類必須覆蓋他們。
④ 抽象類可以派生自一個還湊響雷,可以覆蓋基類的抽象方法也可以不覆蓋,如果不覆蓋,則其派生類必須覆蓋他們。
Ⅱ 、接口:為引用類型。類似於 類 ,在以下三點相似抽象類。
① 不能實例化。
② 包含未實現的方法聲明。
③ 派生類必須實現未實現的方法,抽象類是抽象方法,接口則是所有成員。(不僅是方法,包括其他成員。)
接口除了可以包含方法之外,還可以包含屬性,索引器,事件,而且這些成員都被定義為公有的。除此之外,不能包含任何其他成員。
一個類可以直接繼承多個接口,但只能直接繼承一個類(包括抽象類)
Ⅲ、抽象類和接口的區別
① 類是對 對象 的抽象,把抽象類理解為把類當作對象,抽象成的類叫做抽象類。接口則為行為規范或規定。
② 一個類一次可以實現若干個接口,但是只能擴展一個父類。
③ 接口可以用於支持回調,而繼承並不具備這個特點。
④ 抽象類不能被密封。
⑤ 抽象類實現的具體方法默認為虛的,但實現接口的類中的接口方法卻默認為非虛的。
⑥ 好的接口定義應該是具有專一功能性的,而不是多功能的,否則造成接口污染。如果一個類只是實現了這個接口中一個功能,而不得不去實現接口中的其他方法就叫接口污染。
⑦ 盡量避免使用繼承來實現組件功能,而是使用黑箱復用,即對象組合。因為繼承的層次增多,造成最直接的後果就是當你調用這個類群中的某一類,就必須把他們全部加載到棧中。
⑧ 如果抽象類實現接口,則可以把接口中方法映射到抽象類中作為抽象方法而不必實現,而在抽象類的子類中實現接口中方法。
Ⅳ、抽象類和接口的使用
① 如果預計要創建組件的多個版本,則創建抽象類。抽象類提供簡單的方法來控制組件版本。
② 如果創建的功能將在大范圍的全異對象間使用,則使用接口。如果要設計小而簡練的功能塊,則使用接口。
③ 如果要設計大的功能單元,則使用抽象類,如果要在組件的所有實現間提供通用的已實現功能,則使用抽象類。
④ 抽象類主要用於關系密切的對象,而接口適合為不想關的類提供通用功能。
網上一個挺好的例子:
飛機會飛,鳥會飛,它們都實現了同一個 接口 ”飛“,但 波音747 屬於 飛機 抽象類,鴿子屬於 鳥 抽象類