abstract 修飾符用於表示所修飾的類是不完整的,並且它只能用作基類。抽象類別與非抽象類別在以下方面是不同的:
抽象類別不能直接執行個體化,並且對抽象類別使用 new 運算子是編譯時間錯誤。雖然一些變數和值在編譯時間的類型可以是抽象的,但是這樣的變數和值必須或者為 null,或者含有對非抽象類別的執行個體的引用(此非抽象類別是從抽象類別派生的)。
允許(但不要求)抽象類別包含抽象成員。
抽象類別不能被密封。
當從抽象類別派生非抽象類別時,這些非抽象類別必須具體實現所繼承的所有抽象成員,從而重寫那些抽象成員。
在下面的樣本中
abstract class A
{
public abstract void F();
}
abstract class B: A
{
public void G() {}
}
class C: B
{
public override void F() {
// actual implementation of F
}
}
抽象類別 A 引入抽象方法 F。類 B 引入另一個方法 G,但由於它不提供 F 的實現,B 也必須聲明為抽象類別。類 C 重寫 F,並提供一個具體實現。由於 C 中沒有了抽象成員,因此可以(但並非必須)將 C 聲明為非抽象類別。
與非抽象類別類似,抽象類別也必須為在該類的基類列表中列出的介面的所有成員提供它自己的實現。但是,允許抽象類別將介面方法映射到抽象方法上。例如
interface IMethods
{
void F();
void G();
}
abstract class C: IMethods
{
public abstract void F();
public abstract void G();
}
這裡,IMethods 的實現將 F 和 G 映射到抽象方法上,這些抽象方法必須在從 C 派生的非抽象類別中重寫。
注意:顯式介面成員實現本身不能是抽象的,但是當然允許顯式介面成員實現調用抽象方法。例如
interface IMethods
{
void F();
void G();
}
abstract class C: IMethods
{
void IMethods.F() { FF(); }
void IMethods.G() { GG(); }
protected abstract void FF();
protected abstract void GG();
}
這裡,從 C 派生的非抽象類別被要求重寫 FF 和 GG,從而提供 IMethods 的實際實現。