【轉】C#之繼承

來源:互聯網
上載者:User

標籤:get   事件   body   繼承方式   ace   類的建構函式   介面繼承   gif   method   

一.繼承的類型
  在物件導向的編程中,有兩種截然不同繼承類型:實現繼承和介面繼承
  1.實現繼承和介面繼承
  *實現繼承:表示一個類型派生於基底類型,它擁有該基底類型的所有成員欄位和函數。在實現繼承中,衍生類別型採用基底類型的每個函數的實現代碼,除非在衍生類別型的定義中指定某個函數的實現代碼。在需要給現有的類型添加功能,或許多相關的類型共用一組重要的公用功能時,可以使用這種類型的繼承。
  *介面繼承:表示一個類型只繼承了函數的簽名,沒有繼承任何的代碼。在需要指定該類型具有某些可用的特性時,最好使用這種類型的繼承。
  2.多重繼承
  C#不支援多重繼承,但C#允許類型派生自多個介面————多重介面繼承。這說明,C#類可以派生自另一個類和任意多個介面。更準確的說,因為System.Object是一個公用的基類,所以每個C#(除Object之外)都有一個基類,還可以有任意多個介面。
  3.結構的繼承
  使用結構的一個限制是結構不支援實現繼承,但每個結構都自動派生自System.ValueType。不能編碼實作類別型層次的結構,但結構可以實現介面。

二.繼承的實現
  文法:
  class MyDreved:BaseClass
  {

  }
  如果類或結構也派生自介面,則用逗號分隔列表中的基類和介面:
  class MyDreved:BaseClass,IIntenface1,IIntenface2
  {

  }

  如果在類定義中沒有指定基類,C#編譯器就假定System.Object是基類。

  1.虛方法
  把一個基類函式宣告為virtual,就可以在任何衍生類別中重寫(override)該函數:
  class BaseClass
  {
    public virtual void VirtualMethod()
    {
      //
    }
  }

  也可以把屬性聲明為virtual。對於虛屬性或重寫屬性,文法與非虛屬性相同,但要在定義中添加virtual關鍵字:
  public virtual string Name
  {
    get;set;
  }

  C#中虛函數的概念與標準OOP的概念相同:可以在衍生類別中重寫虛函數。在調用方法時,會調用該衍生類別的合適方法。在C#中,函數預設情況下不是虛的,但(除了建構函式)可以顯式的聲明為virtual。
  在衍生類別中重寫一個函數時,要使用override關鍵字顯示聲明:
  class MyDreved: BaseClass
  {
    public override void VirtualMethod()
    {
      //
    }
  }

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

  2.隱藏方法
  如果簽名相同的方法在基類和衍生類別中都進行了聲明,但該方法沒有分別聲明為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 ACLASS IS B*/

 

  在大多數情況下,是要重寫方法,而不是隱藏方法,因為隱藏方法會造成對於給定類的執行個體調用錯誤的方法。但是,C#文法會在編譯時間收到這個潛在錯誤的警告。

  在C#中,要隱藏一個方法應使用new 關鍵字聲明,這樣在編譯時間就不會發出警告:
  class A 
  {
    public void a()
    {
      Console.WriteLine(‘CLASS is A‘);
    } 
  }

  class B:A
  {
    public new void a()
    {
       Console.WriteLine(‘CLASS is B‘);
    }
  }

  3.調用函數的基類版本
  C#可以從衍生類別中調用方法的基本版本:base.<MethodName>()
  class MyDreved: BaseClass
  {
    public override void VirtualMethod()
    {
      base.VirtualMethod();
    }
  }
  可以使用base.<MethodName>()文法調用基類中的任何方法,不必從同一方法的重載中調用它。

  4.抽象類別和抽象函數
  C#允許把類和函式宣告為abstract.抽象類別不能執行個體化,而抽象不能直接實現,必須在非抽象的衍生類別中重寫。顯然抽象函數也是虛擬(儘管不需要提供virtual,實際上,也不能提供該關鍵字)。
  如果類包含抽象函數,則該類也是抽象的,也必須聲明為抽象的:
  abstract class Building
  {
    public abstract void Cal();
  }

  抽象類別中不能聲明非抽象方法,但可以聲明其它的非抽象成員。

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

  }

  class B:A //報錯
  {

  }

  如果基類上不希望有重寫的方法和屬性,就不要把它聲明為virtual.

  6.衍生類別的建構函式
  假定沒有為任何類定義任何顯示的建構函式,編譯器就會為所有的類提供預設的初始化建構函式,在背景編譯器可以很好的解決類的階層中的問題,每個類中的每個欄位都會初始化為對應的預設值。
  在建立衍生類別的執行個體時,實際上會有多個建構函式起作用。要執行個體化的類的建構函式本身不能初始化類,還必須調用基類中的建構函式。
  建構函式的調用順序是先調用Object,在按照階層調用基類的建構函式,由基類到父類,直到到達要執行個體化的類為止。在這個過程中,每個建構函式都初始化它自己的類中的欄位。因為最先調用的總是基類的建構函式,所以衍生類別在執行過程中可以訪問任何基類的成員,因為基類已經構造出來了,其欄位也初始化了。

  *在階層中添加無參數的建構函式
    在階層中添加一個無參數的建構函式會替換預設的建構函式,所以在執行過程中,會預設調用基類中添加的無參數的建構函式。其它方面不變。
  *在階層中添加帶參數的建構函式
  在階層中要調用這個帶參數的建構函式,需要在父類的建構函式中顯示調用:

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,還可以指定一項的本質,如方法是virtual或abstract.
  1.可見度修飾符
  修飾符        應用於                  說明
  public           所有類和成員              任何代碼可以訪問
  protected          類的成員和內嵌類            只有在類內部和衍生類別中訪問
  internal          所有類和成員              只有在類內部和包含它的程式集中訪問
  private         類的成員和內嵌類            只有在類內部訪問
  protected internal  類的成員和內嵌類            只有在類內部,衍生類別中和包含它的程式集中訪問

  不能把類定義為protected,private,protected internal,因為這些修飾符對於包含在名稱空間中的類型沒有意義。因此這些修飾符只能應用於成員。但是可以用這些修飾符定義嵌套的類(內嵌類,包含在其它類中的類),因為在這種情況下,類也具有成員的狀態:
  public class OuterClass
  {
    protected class InnerClass
    {

    }
  }

  2.其它修飾符
  修飾符    應用於      說明
  new        函數       隱藏函數
  static     所有成員     靜態
  virtual    函數        成員可以由衍生類別重寫
  abstract      類,函數     抽象
  override     函數        重寫虛擬和抽象的成員
  sealed      類,方法,屬性       不能繼承和重寫
  extern       僅靜態方法    成員在外部用另一種語言實現

四.介面
  public interface IDisposable
  {
    void Dispose();
  }

  聲明介面在文法上和聲明抽象類別完全相同,但不允許提供任何成員的實現方式。抽象類別可以提供除方法之外的其它成員的實現方式,比如屬性。
  一般情況下,介面只能包含方法,屬性,索引器和事件的聲明。
  不能執行個體化介面,介面即不能有建構函式,也不能有欄位。介面定義也不允許包含運算子多載。
  在介面中不允許聲明關於成員的修飾符。介面成員總是公有的,不能聲明為虛擬和靜態。如果需要,在實現的類中聲明。

  實現介面的類必須實現介面的所有成員。
  介面可以彼此繼承,其方式與類的繼承方式相同。

【轉】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.