可以,有兩種方式:
class BaseClass {
public virtual void F() => Console.WriteLine("BaseClass.F");
}
abstract class Derive1 : BaseClass {
public abstract new void F(); // 隱藏基底 F,新增虛擬槽位
}
F() 仍執行基底實作F()
abstract class Derive2 : BaseClass {
public abstract override void F(); // 覆寫基底虛擬槽位並標記為抽象
}
class Concrete : Derive2 {
public override void F() => Console.WriteLine("Concrete.F");
}
F() 會動態分派至 Concrete.F()可以繼承基底虛擬方法,但不能宣告新的虛擬方法
class Base { public virtual void F() => Console.WriteLine("Base.F"); }
sealed class Derived : Base {
// 基底 F 隱式變為 sealed override(因無後代可覆寫)
// 錯誤:密封類別不能宣告新虛擬方法
// public virtual void G() { }
}
using System;
class BaseClass { public virtual void F() => Console.WriteLine("BaseClass.F"); }
abstract class Derive1 : BaseClass { public abstract new void F(); }
abstract class Derive2 : BaseClass { public abstract override void F(); }
class Concrete1 : Derive1 { public override void F() => Console.WriteLine("Concrete1.F"); }
class Concrete2 : Derive2 { public override void F() => Console.WriteLine("Concrete2.F"); }
sealed class SealedDerived : BaseClass { }
class Program {
static void Main() {
BaseClass b1 = new Concrete1();
BaseClass b2 = new Concrete2();
BaseClass b3 = new SealedDerived();
b1.F(); // BaseClass.F (new 隱藏,多型失效)
b2.F(); // Concrete2.F (abstract override,多型生效)
b3.F(); // BaseClass.F (密封類別繼承基底虛擬方法)
Console.ReadKey();
}
}
BaseClass.F
Concrete2.F
BaseClass.F
override:在同一槽位覆寫方法指標new:新增槽位,基底槽位保留abstract override:清空槽位指標(標記為 pure virtual),強制後代填寫sealed class:v-table 固定,無後代可修改
需要強制子類別實作?
├─ 是 → 保留多型? → 是 → abstract override
│ └─ 否 → abstract new
└─ 否 → 提供預設實作? → 是 → virtual
└─ 否 → 介面/抽象類別定義契約