由於抽象類本身表達的是抽象的概念,因此類中的許多方法並不一定要有具體的實現,而只是留出一個接口來作為派生類重載的界面。舉一個簡單的例子,“圖形”這個類是抽象的,它的成員方法“計算圖形面積”也就沒有實際的意義。面積只對“圖形”的派生類比如“圓”、“三角形”這些非抽象的概念才有效,那麼我們就可以把基類“圖形”的成員方法“計算面積”聲明為抽象的,具體的實現交給派生類通過重載來實現。
一個方法聲明中如果加上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並提供自己的實現。