首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 抽象覆寫虛擬方法與密封類別虛擬方法限制:進階繼承機制解析

     編輯:關於C語言

抽象方法可否覆寫基底虛擬方法?

可以,有兩種方式:

方式一:new + abstract(隱藏基底槽位)


class BaseClass {
    public virtual void F() => Console.WriteLine("BaseClass.F");
}
abstract class Derive1 : BaseClass {
    public abstract new void F(); // 隱藏基底 F,新增虛擬槽位
}
  • 基底類別參考呼叫 F() 仍執行基底實作
  • 衍生類別必須實作新的 F()
  • 適用:刻意中斷繼承鏈、重新定義契約

方式二:abstract override(抽象覆寫,保留槽位)


abstract class Derive2 : BaseClass {
    public abstract override void F(); // 覆寫基底虛擬槽位並標記為抽象
}
class Concrete : Derive2 {
    public override void F() => Console.WriteLine("Concrete.F");
}
  • 基底類別參考呼叫 F() 會動態分派至 Concrete.F()
  • 適用:Template Method 模式,強制子類別實作核心步驟但保留多型

密封類別能否有虛擬方法?

可以繼承基底虛擬方法,但不能宣告新的虛擬方法


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

核心原理:虛擬方法表

  • 每個含虛擬方法的類別有一個 v-table(虛擬方法表)
  • override:在同一槽位覆寫方法指標
  • new:新增槽位,基底槽位保留
  • abstract override:清空槽位指標(標記為 pure virtual),強制後代填寫
  • sealed class:v-table 固定,無後代可修改

設計決策樹

需要強制子類別實作?
├─ 是 → 保留多型? → 是 → abstract override
│                    └─ 否 → abstract new
└─ 否 → 提供預設實作? → 是 → virtual
                      └─ 否 → 介面/抽象類別定義契約
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved