由於抽象類本身表達的是抽象的概念,因此類中的許多方法並不一定要有具體的實現,而只是留出一個接口來作為派生類重載的界面。舉一個簡單的例子,“圖形”這個類是抽象的,它的成員方法“計算圖形面積”也就沒有實際的意義。面積只對“圖形”的派生類比如“圓”、“三角形”這些非抽象的概念才有效,那麼我們就可以把基類“圖形”的成員方法“計算面積”聲明為抽象的,具體的實現交給派生類通過重載來實現。
一個方法聲明中如果加上abstract修飾符,我們稱該方法為抽象方法(abstract method)。
如果一個方法被聲明也是抽象的,那麼該方法默認也是一個虛方法。事實上,抽象方法是一個新的虛方法,它不提供具體的方法實現代碼。我們知道,非虛的派生類要求通過重載為繼承的虛方法提供自己的實現,而抽象方法則不包含具體的實現內容,所以方法聲明的執行體中只有一個分號“;”。
只能在抽象類中聲明抽象方法。對抽象方法,不能再使用static或virtual修飾符,而且方法不能有任何可執行代碼,哪怕只是一對大括號中間加一個分號“{;}”都不允許出現,只需要給出方法的原型就可以了。
“交通工具”的“鳴笛”這個方法實際上是沒有什麼意義的,接下來我們利用抽象方法的概念繼續改寫汽車類的例子:
程序清單14-6:
using System; abstruct class Vehicle //定義汽車類 { public int wheels; //公有成員:輪子個數 protected float weight; //保護成員:重量 public Vehicle(int w,float g){ wheels=w; weight=g; } public abstract void Speak(); }; class Car:Vehicle //定義轎車類 { int passenger; //私有成員:乘客數 public Car(int w,float g,int p):base(w,g) { wheels=w; weight=g; passengers=p; } public override void Speak(){ Console.WriteLine("The car is speaking:Di-di!"); } } class Truck:Vehicle //定義卡車類 { int passengers; //私有成員:乘客數 float load; //私有成員:載重量 public Truck(int w,float g,int p,float l):base(w,g) { wheels=w; weight=g; passengers=p; load=l; } public override void Speak(){ Console.WriteLine("The truck is speaking:Ba-ba!"); } }
還要注意,抽象方法在派生類中不能使用base關鍵字來進行訪問。例如,下面的代碼在編譯時會發生錯誤:
class A
{
public abstract void F();
}
class B:A
{
public override void F(){
base.F(); //錯誤,base.F是抽象方法
}
}
我們還可以利用抽象方法來重載基類的虛方法,這時基類中虛方法的執行代碼就被“攔截”了。下面的例子說明了這一點:
class A { public virtual void F(){ Console.WriteLine("A.F"); } } abstract class B:A { public abstract override void F(); } class C:B { public override void F(){ Console.WriteLine("C.F"); } }
類A聲明了一個虛方法F,派生類B使用抽象方法重載了F,這樣B的派生類C就可以重載F並提供自己的實現。