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

C# 介面、抽象類、抽象方法、虛方法 四大概念辨析與面試陷阱

     編輯:關於C語言

這四個概念是 C# 多態機制的基石,混淆它們會導致設計缺陷與面試失利。本文通過**語法對比表**、**代碼驗證**、**經典面試題 (new vs override)** 三維度,建立清晰的認知邊界。

一、 介面 vs 抽象類:語法與語義雙維對比

維度介面 interface抽象類 abstract class
實例化不可不可
字段/狀態不可 (C# 8+ 僅 static)可 (instance/static/readonly/const)
方法實現不可 (C# 8+ default 除外)可 (虛/非虛/抽象/靜態)
構造函數不可可 (protected 供派生調用)
訪問修飾符默認 public (C# 8+ 可 private/protected/internal)完整支援
繼承關係多實現 (: IFoo, IBar)單繼承 (: Base)
語義契約/能力骨架/身份

二、 抽象方法 vs 虛方法:同與異

特性抽象方法 abstract虛方法 virtual
所屬類型僅抽象類抽象類/具體類
方法體不可有 (分號結尾)可有 (默認實現)
派生類義務必須 override (除非派生類也是 abstract)可選 override
關鍵字abstractvirtual
本質強制契約可選擴展點

抽象方法 = 無方法體的虛方法 + 強制覆寫語義。

三、 綜合代碼示範


// 手機抽象類:共享狀態 + 抽象核心行為 + 虛擬可選行為
public abstract class MobilePhone {
    private string _logo;
    public string Logo { get => _logo; set => _logo = value; }
    
    public abstract void Call();           // 必須實現
    public virtual void CallAgain() {      // 可選覆寫
        Console.WriteLine("我再打一個電話");
    }
}

// 介面:純能力契約
public interface IClock { void Alarm(); }
public interface IMusicPlayer { void PlayMusic(); }

// 具體實現:單繼承 + 多實現
public class Nokia : MobilePhone, IClock, IMusicPlayer {
    public override void Call() => Console.WriteLine("NOKIA打電話沒問題");
    public void Alarm() => Console.WriteLine("NOKIA有鬧鐘");
    public void PlayMusic() => Console.WriteLine("NOKIA能聽歌");
    public override void CallAgain() => Console.WriteLine("算了,不打了"); // 覆寫虛方法
}

// 實例化可無 new (結構體特性,類需 new)
// MobilePhone mp = new Nokia(); // 多態調用

四、 經典面試陷阱:new vs override 隱藏與覆寫

代碼


public class A5 {
    public virtual void MethodA() => Console.WriteLine("A5.MethodA");
    public virtual void MethodB() => MethodA(); // 調用虛方法
}
public class B5 : A5 {
    public new void MethodA() => Console.WriteLine("B5.MethodA"); // 隱藏!非覆寫
}
// 測試
var b5 = new B5();
b5.MethodB(); // 輸出什麼?

答案與解析

輸出:A5.MethodA

  • B5.MethodA 用 new **隱藏** 了基類方法,**未覆寫**虛方法槽位。
  • A5.MethodB 內部調用 MethodA() 走**虛方法分發**,查找槽位發現仍是 A5.MethodA。
  • new 僅影響**靜態綁定** (編譯期類型為 B5 時直接調用),不影響**動態分發**。

核心法則

  1. override = **替換虛方法槽位** (動態分發生效)。
  2. new = **新增同名槽位,遮蔽基類** (僅靜態綁定生效)。
  3. 永不在虛方法鏈中使用 new,除非極其清楚後果 (如斷開多態鏈)。

五、 實例化無 new 的條件 (結構體專屬)

  • 結構體**無字段** 或 **字段均為值類型且已逐個初始化** 時,可 MyStruct s; s.Field = 1;。
  • 類**必須** new (分配堆內存、調用構造函數)。

介面定義「能做什麼」,抽象類定義「是什麼」;抽象方法強制「必須做」,虛方法建議「可以做」;override 延續多態,new 切斷多態。刻入肌肉記憶,代碼零 Bug,面試零失手。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved