一. 繼承基礎知識
為了提高軟件模塊的可復用性和可擴充性,以便提高軟件的開發效率,我們總是希望能夠利用前人或自己以前的開發成果,同時又希望在自己的開發過程中能夠有足夠的靈活性,不拘泥於復用的模塊。C#這種完全面向對象的程序設計語言提供了兩個重要的特性--繼承性inheritance 和多態性polymorphism。
繼承是面向對象程序設計的主要特征之一,它可以讓您重用代碼,可以節省程序設計的時間。繼承就是在類之間建立一種相交關系,使得新定義的派生類的實例可以繼承已有的基類的特征和能力,而且可以加入新的特性或者是修改已有的特性建立起類的新層次。
現實世界中的許多實體之間不是相互孤立的,它們往往具有共同的特征也存在內在的差別。人們可以采用層次結構來描述這些實體之間的相似之處和不同之處。
圖1 類圖
上圖反映了交通工具類的派生關系。最高層的實體往往具有最一般最普遍的特征,越下層的事物越具體,並且下層包含了上層的特征。它們之間的關系是基類與派生類之間的關系。
為了用軟件語言對現實世界中的層次結構進行模型化,面向對象的程序設計技術引入了繼承的概念。一個類從另一個類派生出來時,派生類從基類那裡繼承特性。派生類也可以作為其它類的基類。從一個基類派生出來的多層類形成了類的層次結構。
注意:C#中,派生類只能從一個類中繼承。這是因為,在C++中,人們在大多數情況下不需要一個從多個類中派生的類。從多個基類中派生一個類這往往會帶來許多問題,從而抵消了這種靈活性帶來的優勢。
C#中,派生類從它的直接基類中繼承成員:方法、域、屬性、事件、索引指示器。除了構造函數和析構函數,派生類隱式地繼承了直接基類的所有成員。看下面示例:
using System ; class Vehicle //定義交通工具(汽車)類 { protected int wheels ; //公有成員:輪子個數 protected float weight ; //保護成員:重量 public Vehicle( ){;} public Vehicle(int w,float g){ wheels = w ; weight = g ; } public void Speak( ){ Console.WriteLine( "交通工具的輪子個數是可以變化的! " ) ; } } ; 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#中的繼承符合下列規則:
1、繼承是可傳遞的。如果C從B中派生,B又從A中派生,那麼C不僅繼承了B中聲明的成員,同樣也繼承了A中的成員。Object 類作為所有類的基類。
2、派生類應當是對基類的擴展。派生類可以添加新的成員,但不能除去已經繼承的成員的定義。
3、構造函數和析構函數不能被繼承。除此以外的其它成員,不論對它們定義了怎樣的訪問方式,都能被繼承。基類中成員的訪問方式只能決定派生類能否訪問它們。
4、派生類如果定義了與繼承而來的成員同名的新成員,就可以覆蓋已繼承的成員。但這並不因為這派生類刪除了這些成員,只是不能再訪問這些成員。
5、類可以定義虛方法、虛屬性以及虛索引指示器,它的派生類能夠重載這些成員,從而實現類可以展示出多態性。
6、派生類只能從一個類中繼承,可以通過接呂實現多重繼承。
下面的代碼是一個子類繼承父類的例子:
using System ; public class ParentClass { public ParentClass( ) { Console.WriteLine("父類構造函數。"); } public void print( ) { Console.WriteLine("I'm a Parent Class。") ; } } public class ChildClass : ParentClass { public ChildClass( ) { Console.WriteLine("子類構造函數。") ; } public static void Main( ) { ChildClass child = new ChildClass( ) ; child.print( ) ; } }