程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#的繼承機制

C#的繼承機制

編輯:關於C#

14.1.1 C#繼承概述

現實世界中許多實體之間不是相互孤立的,它們往往具有共同的特征,也存在內存的差別。人們可以采用層次結構來描述這些實體之間的相似之處和不同之處。

 

上圖反映了魚類的派生關系。最高層的實體往往具有最一般最普遍的特征,越下層的事物越具體,並且下層包含了上層的特征,它們之間的關系是基類與派生類之間的關系。

為了用軟件語言對現實世界中的層次結構進行模型化,面向對象的程序設計技術引入了繼承的概念。一個類從另一個類派生出來時,派生類從基類那裡繼承特性。派生類也可以作為其他類的基類。從一個基類派生出來的多層類形成了類的層次結構。

注意:C#中,派生類只能從一個類中繼承。這是因為,在C++中,人們在大多數情況下不需要一個從多個類中派生的類。從多個基類中派生一個類,這往往會帶來許多問題,從而抵消了這種靈活性帶來的優勢。

C#中,派生類從它的直接基類中繼承成員:方法、域、屬性、事件、索引指示器。除了構造函數和析構函數,派生類隱式地繼承了直接基類的所有成員。

第十章中提到了一個關於車輛的例子,讓我們再回顧一下這個例子,從中獲得基類與派生類的感性認識。

程序清單14-1:

using System;
class Vehicle //定義汽車類
{
 int wheels; //公有成員:輪子個數
 protected float weight; //保護成員:重量
 public Vehicle(){;}
 public Vehicle(int w,float g){
        wheels=w;
        weight=g;
      }
 public void Speak(){
        Console.WriteLine("the W vehicle is speaking!");
 }
};
class Car:Vehicle //定義轎車類:從汽車類中繼承
{
  int passengers; //私有成員:乘客數
  public Car(int w,float g,int p):base(w,g)
  {
     wheels=w;
     weight=g;
     passengers=p;
  }
}

Vehicle作為基類,體現了“汽車”這個實體具有的公共性質:汽車都有輪子和重量。Car類繼承了Vehicle的這些性質,並且添加了自身的特性:可以搭載乘客。

C#中的繼承符合下列規則:

●繼承是可傳遞的。如果C從B中派生,B又從A中派生,那麼C不僅繼承了B中聲明的成員,同樣也繼承了A中的成員。Object類作為所有類的基類。

●派生類應當是對基類的擴展。派生類可以添加新的成員,但不能除去已經繼承的成員的定義。

●構造函數和析構函數不能被繼承。除此之外的其它成員,不論對它們定義了怎樣的訪問方式,都能被繼承。基類中成員的訪問方式只能決定派生類能否訪問它們。

●派生類如果定義了與繼承而來的成員同名的新成員,就可以覆蓋已繼承的成員。但這並不因為這派生類刪除了這些成員,只是不能再訪問這些成員。

●類可以定義虛文法、虛屬性以及虛索引指示器,它的派生類能夠重載這些成員,從而實現類可以展示出多態性。

14.1.2 覆蓋

我們上面提到,類的成員聲明中,可以聲明與繼承而來的成員同名的成員。這時我們稱派生類的成員覆蓋(hide)了基類的成員。這種情況下,編譯器不會報告錯誤,但會給出一個警告。對派生類的成員使用new關鍵字,可以關閉這個警告。

前面汽車類的例子中,類car繼承了Vehicle的Speak()方法。我們可以給Car類也聲明一個Speak()方法,覆蓋Vehicle中的Speak,見下面的代碼。

程序清單14-2:

using System;
class Vehicle //定義汽車類
{
  public int wheels; //公有成員:輪子個數
  protected float weight; //保護成員:重量
  public Vehicle(){;};
  public Vehicle(int w,float g){
         wheels=w;
         weight=g;
      }
public void Speak(){
       Console.WriteLine("the w vehicle is speaking!");
       }
}
class Car:Vehicle //定義轎車類
{
  int passengers; //私有成員:乘客數
  public Car(int w,float g,int p)
      wheels=w;
      weight=g;
      passengers=p;
  }
  new public void Speak(){
      Console.WriteLine("Di-di!");
  }
}

注意:如果在成員聲明中加上了new關鍵字修飾符,而該成員事實上並沒有覆蓋繼承的成員,編譯器將會給出警告。在一個成員聲明同時使用new和override,則編譯器會報告錯誤。

14.1.3 base保留字

base關鍵字主要是為派生類調用基類提供一個簡寫的方法。我們先看一個例子程序的代碼:

class A
{
 public void F(){
    //F的具體執行代碼
 }
 public int this[int nIndex]{
    get{};
    set{};
 }
}
class B
{
 public void G(){
    int x=base[0];
    base.F();
 }
}

類B從類A中繼承,B的方法G中調用了A的方法F和索引指示器。方法F在進行編譯時等價於:

public void G(){
 int x=(A(this))[0];
       (A(this)).F();
 }

使用base關鍵字對基類成員的訪問格式為:

base   . identifier
base   [ expression-list]
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved