本節課將介紹C#中的繼承,其目的如下:
1.基類的實現
2.類的繼承
3.在派生類中初始化基類
4.如何調用基類成員
5.如何覆蓋基類成員
繼承是面向對象程序設計的主要特征之一,它可以讓你重用代碼,可以節省程序設計的時間。
1.清單8-1 繼承: BaseClass.cs
using System;
public class ParentClass
{
public ParentClass()
{
Console.WriteLine("Parent Constructor.");
}
public void print()
{
Console.WriteLine("I'm a Parent Class.");
}
}
public class ChildClass : ParentClass
{
public ChildClass()
{
Console.WriteLine("Child Constructor.");
}
public static void Main()
{
ChildClass child = new ChildClass();
child.print();
}
}
Output:
Parent Constructor.
Child Constructor.
I'm a Parent Class.
說明
清單8-1演示了兩個類的用法。上面的一個類名為ParentClass, main函數中用到的類名為ChildClass。要做的是創建一個使用父類ParentClass現有代碼的子類ChildClass。
1.首先必須說明ParentClass是ChildClass的基類。
這是通過在ChildClass類中作出如下說明來完成的:"public class ChildClass : ParentClass"。在派生類標識符後面,用分號":" 來表明後面的標識符是基類。C#僅支持單一繼承。因此,你只能指定一個基類。
2.ChildClass的功能幾乎等同於ParentClass。
因此,也可以說ChildClass "就是" ParentClass。在ChildClass 的Main()方法中,調用print() 方法的結果,就驗證這一點。該子類並沒有自己的print()方法,它使用了ParentClass中的 print()方法。在輸出結果中的第三行可以得到驗證。
3.基類在派生類初始化之前自動進行初始化。
注意到清單8-1的輸出結果。ParentClass 類的構造函數在ChildClass的構造函數之前執行。
2.清單 8-2. 派生類同基類進行通信: BaseTalk.cs
using System;
public class Parent
{
string parentString;
public Parent()
{
Console.WriteLine("Parent Constructor.");
}
public Parent(string myString)
{
parentString = myString;
Console.WriteLine(parentString);
}
public void print()
{
Console.WriteLine("I'm a Parent Class.");
}
}
public class Child : Parent
{
public Child() : base("From Derived")
{
Console.WriteLine("Child Constructor.");
}
public void print()
{
base.print();
Console.WriteLine("I'm a Child Class.");
}
public static void Main()
{
Child child = new Child();
child.print();
((Parent)child).print();
}
}
Output:
From Derived
Child Constructor.
I'm a Parent Class.
I'm a Child Class.
I'm a Parent Class.
說明
1.派生類在初始化的過程中可以同基類進行通信。
清單8-2演示了在子類的構造函數定義中是如何實現同基類通信的。分號":"和關鍵字base用來調用帶有相應參數的基類的構造函數。輸出結果中,第一行表明:基類的構造函數最先被調用,其實在參數是字符串"From Derived"。
2.有時,對於基類已有定義的方法,打算重新定義自己的實現。
Child類可以自己重新定義print()方法的實現。Child的print()方法覆蓋了Parent中的 print 方法。結果是:除非經過特別指明,Parent類中的print方法不會被調用。
3.在Child類的 print() 方法中,我們特別指明:調用的是Parent類中的 print() 方法。
方法名前面為"base",一旦使用"base"關鍵字之後,你就可以訪問基類的具有公有或者保護權限的成員。 Child類中的print()方法的執行結果出現上面的第三行和第四行。
4.訪問基類成員的另外一種方法是:通過顯式類型轉換。
在Child類的Main()方法中的最後一條語句就是這麼做的。記住:派生類是其基類的特例。這個事實告訴我們:可以在派生類中進行數據類型的轉換,使其成為基類的一個實例。清單8-2的最後一行實際上執行了Parent類中的 print()方法。
小結
你已經了解了如何創建一個派生類及其基類。你可以對基類成員進行初始化,以及如何對方法進行隱式或者顯式的調用。你也了解了派生類是其基類的一個特例。