C# 繼承

來源:互聯網
上載者:User

標籤:

在編程中也沿用了繼承的概念,在物件導向編程中,如C++和C#中都有類的繼承。 繼承(加上封裝和多態性)是物件導向的編程的三個主要特性(也稱為“支柱”)之一。 繼承用於建立可重用、擴充和修改在其他類中定義的行為的新類。 其成員被繼承的類稱為“基類”,繼承這些成員的類稱為“衍生類別”。 衍生類別只能有一個直接基類。 但是,繼承是可傳遞的。 如果 ClassB 派生出 ClassC,ClassA 派生出 ClassB,則 ClassC 會繼承 ClassB 和 ClassA 中聲明的成員。

v寫在前面

無論是其他社區還是園子裡,關於繼承類的文章或者文章已經可以說是數不勝數了,關於繼承類的話題也是舊調重彈了。寫這篇博文只是為了加深一下自己對繼承的理解,所謂讀書百遍其意自見嘛。這篇博文中部分內容來自我的讀書(C#進階編程從開始接觸C#到現在我已經是第五遍讀了,每次讀都有不一樣的收穫。)筆記,和一些自己的理解。

vC#繼承 1.實現繼承 

如果要聲明派生自另一個類的一個類,就可以使用下面的文法:

    class LearningClass : BasicClass    {    }

如果類(或結構)也派生自介面,則用逗號分隔列表中的基類和介面:

  class LearningClass : BasicClass, BasicInterface, BasicInterface2    {    }

對於結構,文法如下:

    struct LearningStruct : BasicInterface, BasicInterface2    {    }
使用結構的一個限制是結構不支援繼承,但每個結 構都自動派生自system,ValueType。實際上還應更仔細一些:不能編碼實作類別型層次的結構,但結 構可以實現介面。換言之,結構並不支援實現繼承,但支援介面繼承。事實上,定義結構和類可以 總結為:
  • 結構總是派生自system。ValueType,它們還可以派生自任意多個介面。
  • 類總是派生自使用者選擇的另一個類,它們還可以派生自任意多個介面。

在類定義中沒有指定基類,鈄編譯器就假定sysm.叻ect是基類。因此下面的兩段代碼產生相同的結果:

  class LearningClass : Object    {    }    class LearningClass    {    }
2.虛方法virtual: 

有時候我們繼承一個基類的某些方法希望能重新定義這個方法,我們可以把一個基類函式宣告virtual,就可以在任何衍生類別中重寫這個函數:

public class BasicClass    {        public virtual string GetMessage()        {            return "Basic class message";        }    }

C#中虛函數的概念與標準00P的概念相同:可以在衍生類別中重寫虛函數。在調用方法時,會調用該類對象的合適方法。在C#中,函數在預設情況下不是虛擬,但(除了建構函式以外)可以顯 式地聲明為virtual。這遵循C++的方式,即從效能的角度來看,除非顯式指定,否則函數就不是虛 擬的。而在Java中,所有的函數都是虛擬。但C#的文法與C++的文法不同,因為C#要求在派生 類的函數重寫另一個函數時,要使用override關鍵字顯式聲明:

    class LearningClass : BasicClass    {        public override string GetMessage()        {            return "Learning class message";        }    }

重寫方法的文法避免了C++中很容易發生的潛在運行錯誤:當衍生類別的方法簽名無意中與基類 版本略有差別時,該方法就不能重寫基類的方法:在C#中,這會出現一個編譯錯誤,因為編譯器會 認為函數已標記為override,但沒有重寫其基類的方法。

成員欄位和靜態函數都不能聲明為virtual,因為這個概念只對類中的執行個體函數成員有意義。

3.隱藏方法: 

如果簽名相同的方法在基類和衍生類別中都進行了聲明,但該方法沒有分別聲明為virtual和 override,衍生類別方法就會隱藏基類方法。

在大多數清況下,是要重寫方法,而不是隱藏方法,因為隱藏方法會造成對於給定類的執行個體調用 錯誤方法的危險。但是,如下面的例子所示,C#文法可以確保開發人員在編譯時間收到這個潛在錯誤的 警告,從而使隱藏方弦【如果這確實是使用者的本匐更加安全。這也是類庫開發人員得到的版本方面的 · 好處

此時,編譯時間系統會發出警告。在C#中,要隱藏一個方法應使用new關鍵字聲明,如下所示:

  public class LearningClass : BasicClass    {        public new string GetMessage()        {            return "Learning class message";        }    }
4.調用函數的基類版本: 

C#有一種特殊的文法用於從衍生類別中調用方法的基類版本:base.()。例如,假定 衍生類別中的一個方法要返回基類的方法20%的傳回值,就可以使用下面的文法:

    public class BasicClass    {        public virtual float GetPrice()        {            return 1.5f;        }    }    public class LearningClass : BasicClass    {        public float GetPrice()        {            return base.GetPrice() * 0.2f;        }    }

ps:可以使用base.()文法調用基類中的任何方法,不必從同一個方法的重載 中調用它。

5.抽象類別和抽象函數: 

C#允許把類和函式宣告為abstract。抽象類別不能執行個體化,而抽象函數不能直接實現,必須在非抽 象的衍生類別中重寫。顯然,抽象函數本身也是虛擬(儘管也不需要提供virtual關鍵字,實際上,如 果提供了該關鍵字,就會產生一個語法錯誤。如果類包含抽象函數,則該類也是抽象的,也必須聲 明為抽象的:

    public abstract class BasicClass    {        public abstract float GetPrice();    }    public class LearningClass : BasicClass    {        public override float GetPrice()        {            return 0.2f;        }    }
6.密封類和密封方法: 

C#允許把類和方法聲明為sealed。對於類,這表示不能繼承該類;對於方法,這表示不能重寫該方法。

在把類或方法標記為sealed時,最可能的情形是:如果要對庫、類或自己編寫的其他類範圍 之外的類或方法進行操作,則重寫某些功能會導致代碼混亂。也可以因商業原因把類或方法標記為 sealed,以防第三方以違反授權協議的方式擴充該類。但一般情況下,在把類或成員標記為sealed 時要小心,因為這麼做會嚴重限制它的使用方式。即使認為它不能對繼承自一個類或重寫類的某個 成員發揮作用,仍有可能在將來的某個時刻,有人會遇到我們沒有預料到的情形,此時這麼做就很 有用。.NET基底類別庫大量使用了密封類,使希望從這些類中派生出自己的類的第三方開發人員無法訪 問這些類。例如,string就是一個密封類。

把方法聲明為sealed也可以實作類別似的目的,但很少這麼做。

7.修飾符: 

C#共有五種存取修飾詞:public、private、protected、internal、protected internal。作用範圍如下表:

存取修飾詞 說明
public 公有訪問。不受任何限制。
private 私人訪問。只限於本類成員訪問,子類,執行個體都不能訪問。
protected 保護訪問。只限於本類和子類訪問,執行個體不能訪問。
internal 內部訪問。只限於本項目內訪問,其他不能訪問。
protected internal 內部保護訪問。只限於本項目或是子類訪問,其他不能訪問

C#成員類型的可修飾及預設修飾符如下表:

成員類型 預設修飾符 可被修飾符
enum public none
class private public、protected、internal、private、
protected internal
interface public none
struct private public、internal、private

修飾符可以應用於類型的成員,而且有不同的用途:

修飾符 應用於 說明
new 函數成員 成員用相同的簽名隱藏繼承的成員
static 所有成員 成員不作用於類的具體執行個體
virtual 僅函數成員 成員可以由衍生類別重寫
abstract 僅函數成員 虛擬成員定義了成員的簽名,但沒有提供執行個體代碼
override 僅函數成員 成員重寫了繼承的虛擬或抽象成員
sealed 類,方法和屬性 對於類,不能繼承自密封類。對於屬性和方法,成員重寫已繼承的虛擬成員,但任何衍生類別中的任何成員都不能重寫該成員。該修飾符必須與override一起使用
extern 僅靜態[DllImport]方法 成員在外部用另一種語言實現

C# 繼承

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.