C#-繼承(十一)
繼承概念
承用於創建可重用、擴展和修改在其他類中定義的行為的新類
創建一個類的時候,不是要寫全新的數據成員和成員函數,可以指定新的類繼承一個已經存在的類的成員。已有的類稱為基類,新的類稱為派生類
派生類只能有一個直接基類,但一個基類可以有多個直接派生類
例如ClassAnimal派生出ClassMammals,ClassMammals派生出ClassHuman,則ClassHuman會繼承ClassMammals和ClassAnimal中聲明的成員
繼承特點
派生類是對基類的擴展,派生類可以添加新的成員,但不能移除已經繼承的成員的定義
繼承是可以傳遞的。如果C從B中派生,B又從A中派生,那麽C不僅繼承了B中聲明的成員,同樣也繼承了A中聲明的成員
構造函數和析構函數不能被繼承,除此之外其他成員能被繼承。基類中成員的訪問方式只能決定派生類能否訪問它們。
派生類如果定義了與繼承而來的成員同名的新成員,那麽就可以覆蓋已繼承的成員,但這兵不是刪除了這些成員,只是不能再訪問這些成員
類可以定義虛方法、虛屬性及虛索引指示器,它的派生類能夠重載這些成員,從而使類可以展示出多態性
派生類只能從一個類中繼承,可以通過接口來實現多重繼承
基本語法
1 class MyClass : BaseClass 2 { 3 // 方法體 4 }
如果在類定義中沒有指定基類,默認System.Object是基類
虛方法
將一個基類函數聲明為virtual,則在任何一個派生類中可以重寫該函數
1 clss BaseClass 2 { 3 public virtual void VirtualMethod() 4 { 5 // 方法體 6 } 7 }
在派生類中使用override重寫函數
1 class MyClass :BaseClass 2 { 3 public override void VirtualMethod() 4 { 5 // 方法體 6 } 7 }
將屬性聲明為virtual
1 publicvirtual string Name 2 { 3 get;set; 4 }
隱藏方法
在沒有聲明virtual和override的情況下,簽名相同的方法在基類和派生類中都進行了聲明
在派生類方法中會隱藏基類方法
但是隱藏方法會造成對於給定類的實例調用錯誤的方法
C#語法在編譯時會收到這個潛在錯誤的警告
所以要隱藏一個方法時用new關鍵字聲明,會避免編譯時就發出警告錯誤
1 class ClassBase 2 { 3 public void BaseMethod() 4 { 5 // 方法體 6 } 7 } 8 9 10 class MyClass : ClassBase 11 { 12 public new void MyClass() 13 { 14 // 方法體 15 } 16 }
抽象類
C#允許把類和函數聲明為abstract
抽象類不能實例化,而抽象不能直接實現,必須在非抽象的派生類中重寫
如果類包含抽象函數,則該類也是抽象的,也必須聲明為抽象的
抽象類中不能聲明非抽象方法,但可以聲明其它的非抽象成員
抽象類語法:
1 abstract class MyClass 2 { 3 public abstract void MyMethod(); 4 }
抽象方法沒有實現,所以方法定義後面是分號,而不是常規的方法塊
抽象類的派生類必須實現所有抽象方法
當抽象類從基類繼承虛方法時,抽象類可以使用抽象方法重寫該虛方法
密封類和類成員
密封類的聲明是在類定義前面放置關鍵字 sealed
密封類不能用作基類
密封類禁止派生
在對基類的虛成員進行重寫的派生類上的類成員、方法、字段、屬性或事件可以將該成員聲明為密封成員
方法是在類成員聲明中將sealed關鍵字置於override關鍵字的前面
1 public sealed class ClassSealed 2 { 3 // 屬性,方法 4 } 5 6 public class ClassSunSealed : ClassSealed 7 { 8 public sealed override void SealdMethod() { } 9 }
接口
接口是一種引用類型,有點像僅包含抽象成員的抽象基類
類在從接口實現時必須為該接口的所有成員提供實現。 類雖然只能從一個直接基類派生,但可以實現多個接口
不能實例化接口,接口即不能有構造函數,也不能有字段。接口定義也不允許包含運算符重載
接口中不允許聲明關於成員的修飾符,但是可以在實現的類中作聲明
接口成員總是公有的
實現接口的類必須實現接口的所有成員
接口之間的繼承和類的繼承方式相同
1 public interface IDisposable 2 { 3 void Dispose(); 4 }
C#-繼承(十一)