您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“C#繼承怎么實現(xiàn)”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“C#繼承怎么實現(xiàn)”吧!
在面向?qū)ο蟮木幊讨?,有兩種截然不同繼承類型:實現(xiàn)繼承和接口繼承
*實現(xiàn)繼承:表示一個類型派生于基類型,它擁有該基類型的所有成員字段和函數(shù)。在實現(xiàn)繼承中,派生類型采用基類型的每個函數(shù)的實現(xiàn)代碼,除非在派生類型的定義中指定某個函數(shù)的實現(xiàn)代碼。在需要給現(xiàn)有的類型添加功能,或許多相關(guān)的類型共享一組重要的公共功能時,可以使用這種類型的繼承。
*接口繼承:表示一個類型只繼承了函數(shù)的簽名,沒有繼承任何的代碼。在需要指定該類型具有某些可用的特性時,最好使用這種類型的繼承。
C#不支持多重繼承,但C#允許類型派生自多個接口————多重接口繼承。這說明,C#類可以派生自另一個類和任意多個接口。更準(zhǔn)確的說,因為System.Object是一個公共的基類,所以每個C#(除Object之外)都有一個基類,還可以有任意多個接口。
使用結(jié)構(gòu)的一個限制是結(jié)構(gòu)不支持實現(xiàn)繼承,但每個結(jié)構(gòu)都自動派生自System.ValueType。不能編碼實現(xiàn)類型層次的結(jié)構(gòu),但結(jié)構(gòu)可以實現(xiàn)接口。
語法:
class MyDreved:BaseClass { }
如果類或結(jié)構(gòu)也派生自接口,則用逗號分隔列表中的基類和接口:
class MyDreved:BaseClass,IIntenface1,IIntenface2 { }
如果在類定義中沒有指定基類,C#編譯器就假定System.Object是基類。
把一個基類函數(shù)聲明為virtual,就可以在任何派生類中重寫(override)該函數(shù):
class BaseClass { public virtual void VirtualMethod() { // } }
也可以把屬性聲明為virtual。對于虛屬性或重寫屬性,語法與非虛屬性相同,但要在定義中添加virtual關(guān)鍵字:
public virtual string Name { get;set; }
C#中虛函數(shù)的概念與標(biāo)準(zhǔn)OOP的概念相同:可以在派生類中重寫虛函數(shù)。在調(diào)用方法時,會調(diào)用該派生類的合適方法。在C#中,函數(shù)默認(rèn)情況下不是虛的,但(除了構(gòu)造函數(shù))可以顯式的聲明為virtual。
在派生類中重寫一個函數(shù)時,要使用override關(guān)鍵字顯示聲明:
class MyDreved: BaseClass { public override void VirtualMethod() { // } }
成員字段和靜態(tài)函數(shù)都不能聲明為virtual,因為這個概念只對類中的實例函數(shù)成員有意義。
如果簽名相同的方法在基類和派生類中都進行了聲明,但該方法沒有分別聲明為virtual和override,派生類方法就會隱藏基類方法。
class A { public void a() { Console.WriteLine('CLASS is A'); } } class B:A { public void a() { Console.WriteLine('CLASS is B'); } } class client { static void main() { B b=new B(); A a=b; a.a(); b.a(); } } /*輸出 CLASS IS A CLASS IS B */
在大多數(shù)情況下,是要重寫方法,而不是隱藏方法,因為隱藏方法會造成對于給定類的實例調(diào)用錯誤的方法。但是,C#語法會在編譯時收到這個潛在錯誤的警告。
在C#中,要隱藏一個方法應(yīng)使用new 關(guān)鍵字聲明,這樣在編譯時就不會發(fā)出警告:
class A { public void a() { Console.WriteLine('CLASS is A'); } } class B:A { public new void a() { Console.WriteLine('CLASS is B'); } }
C#可以從派生類中調(diào)用方法的基本版本:base.<MethodName>()
class MyDreved: BaseClass { public override void VirtualMethod() { base.VirtualMethod(); } }
可以使用base.<MethodName>()語法調(diào)用基類中的任何方法,不必從同一方法的重載中調(diào)用它。
C#允許把類和函數(shù)聲明為abstract.抽象類不能實例化,而抽象不能直接實現(xiàn),必須在非抽象的派生類中重寫。顯然抽象函數(shù)也是虛擬的(盡管不需要提供virtual,實際上,也不能提供該關(guān)鍵字)。
如果類包含抽象函數(shù),則該類也是抽象的,也必須聲明為抽象的:
abstract class Building { public abstract void Cal(); }
抽象類中不能聲明非抽象方法,但可以聲明其它的非抽象成員。
C#允許把類和方法聲明為sealed。對于類,這表示不能繼承該類;對于方法,表示不能重寫該方法。
sealed class A { } class B:A //報錯 { }
如果基類上不希望有重寫的方法和屬性,就不要把它聲明為virtual.
假定沒有為任何類定義任何顯示的構(gòu)造函數(shù),編譯器就會為所有的類提供默認(rèn)的初始化構(gòu)造函數(shù),在后臺編譯器可以很好的解決類的層次結(jié)構(gòu)中的問題,每個類中的每個字段都會初始化為對應(yīng)的默認(rèn)值。
在創(chuàng)建派生類的實例時,實際上會有多個構(gòu)造函數(shù)起作用。要實例化的類的構(gòu)造函數(shù)本身不能初始化類,還必須調(diào)用基類中的構(gòu)造函數(shù)。
構(gòu)造函數(shù)的調(diào)用順序是先調(diào)用Object,在按照層次結(jié)構(gòu)調(diào)用基類的構(gòu)造函數(shù),由基類到父類,直到到達要實例化的類為止。在這個過程中,每個構(gòu)造函數(shù)都初始化它自己的類中的字段。因為最先調(diào)用的總是基類的構(gòu)造函數(shù),所以派生類在執(zhí)行過程中可以訪問任何基類的成員,因為基類已經(jīng)構(gòu)造出來了,其字段也初始化了。
*在層次結(jié)構(gòu)中添加無參數(shù)的構(gòu)造函數(shù) 在層次結(jié)構(gòu)中添加一個無參數(shù)的構(gòu)造函數(shù)會替換默認(rèn)的構(gòu)造函數(shù),所以在執(zhí)行過程中,會默認(rèn)調(diào)用基類中添加的無參數(shù)的構(gòu)造函數(shù)。其它方面不變。
*在層次結(jié)構(gòu)中添加帶參數(shù)的構(gòu)造函數(shù) 在層次結(jié)構(gòu)中要調(diào)用這個帶參數(shù)的構(gòu)造函數(shù),需要在父類的構(gòu)造函數(shù)中顯示調(diào)用:
public abstract class GenericCustomer { private string name; public GenericCustomer() { name = "<no name>"; } public GenericCustomer(string name) { this.name = name; } public string Name { get {return name;} set {name = value;} } } public class Nevermore60Customer : GenericCustomer { private string referrerName; private uint highCostMinutesUsed; ublic Nevermore60Customer(string name) : this(name, " <None>") { } public Nevermore60Customer(string name, string referrerName) : base(name) { this.referrerName = referrerName; } public string ReferrerName { get {return referrerName;} set {referrerName = value;} } }
修飾符可以指定方法的可見性:如public或private,還可以指定一項的本質(zhì),如方法是virtual或abstract.
修飾符 | 應(yīng)用于 | 說明 |
---|---|---|
public | 所有類和成員 | 任何代碼可以訪問 |
protected | 類的成員和內(nèi)嵌類 | 只有在類內(nèi)部和派生類中訪問 |
internal | 所有類和成員 | 只有在類內(nèi)部和包含它的程序集中訪問 |
private | 類的成員和內(nèi)嵌類 | 只有在類內(nèi)部訪問 |
protected internal | 類的成員和內(nèi)嵌類 | 只有在類內(nèi)部,派生類中和包含它的程序集中訪問 |
不能把類定義為protected,private,protected internal,因為這些修飾符對于包含在名稱空間中的類型沒有意義。因此這些修飾符只能應(yīng)用于成員。但是可以用這些修飾符定義嵌套的類(內(nèi)嵌類,包含在其它類中的類),因為在這種情況下,類也具有成員的狀態(tài):
public class OuterClass { protected class InnerClass { } }
修飾符 | 應(yīng)用于 | 說明 |
---|---|---|
new | 函數(shù) | 隱藏函數(shù) |
static | 所有成員 | 靜態(tài) |
virtual | 函數(shù) | 成員可以由派生類重寫 |
abstract | 類,函數(shù) | 抽象 |
override | 函數(shù) | 重寫虛擬和抽象的成員 |
sealed | 類,方法,屬性 | 不能繼承和重寫 |
extern | 僅靜態(tài)方法 | 成員在外部用另一種語言實現(xiàn) |
public interface IDisposable { void Dispose(); }
聲明接口在語法上和聲明抽象類完全相同,但不允許提供任何成員的實現(xiàn)方式。抽象類可以提供除方法之外的其它成員的實現(xiàn)方式,比如屬性。
一般情況下,接口只能包含方法,屬性,索引器和事件的聲明。
不能實例化接口,接口即不能有構(gòu)造函數(shù),也不能有字段。接口定義也不允許包含運算符重載。
在接口中不允許聲明關(guān)于成員的修飾符。接口成員總是公有的,不能聲明為虛擬和靜態(tài)。如果需要,在實現(xiàn)的類中聲明。
實現(xiàn)接口的類必須實現(xiàn)接口的所有成員。
接口可以彼此繼承,其方式與類的繼承方式相同。
到此,相信大家對“C#繼承怎么實現(xiàn)”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。