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

C# 介面隱式與顯式實作完整解析:語法、差異與適用場景

     編輯:ASP.NET 基礎

語法對照

隱式實作


interface IAnimal {
    void Speak();
}

class Dog : IAnimal {
    public void Speak() { Console.WriteLine("Woof!"); } // public 必須
}

// 呼叫方式:類別、介面皆可
Dog d = new Dog();
d.Speak();           // OK

IAnimal a = d;
a.Speak();           // OK

顯式實作


interface IAnimal {
    void Speak();
}

class Cat : IAnimal {
    void IAnimal.Speak() { Console.WriteLine("Meow~"); } // 無 public、無 abstract、介面名稱前綴
}

// 呼叫方式:僅透過介面
Cat c = new Cat();
// c.Speak();        // 編譯錯誤:類別實例不可見

IAnimal a = c;
a.Speak();           // OK

// 強制轉型呼叫
((IAnimal)c).Speak(); // OK
(c as IAnimal)?.Speak(); // OK

核心差異總表

特性隱式實作顯式實作
存取修飾詞必須 public不可寫存取修飾詞 (預設 private)
類別實例可見性可見不可見
介面參考可見性可見可見
虛擬/覆寫支援可 virtual/override不可 (密封),但可在衍生類重新實作
多介面同名稱方法衝突無法區分,單一實作服務所有介面可分別實作 IA.Method()、IB.Method()
預設介面方法 (C# 8+)可選擇性覆寫不可覆寫預設實作

適用場景決策指南

✅ 使用隱式實作的情況

  • 類別**主要**實作單一介面,且該方法屬於類別核心公用 API。
  • 需要支援多型覆寫 (virtual/override)。
  • 希望類別消費者直接呼叫,無須轉型。
  • 介面方法語意與類別職責高度一致 (如 IList.Add → List.Add)。

✅ 使用顯式實作的情況

  • 實作多個介面且有同名方法:

interface IPrintable { void Print(); }
interface IScannable { void Print(); } // 同名但語意不同

class MultiFunctionDevice : IPrintable, IScannable {
    void IPrintable.Print() => Console.WriteLine("Printing document...");
    void IScannable.Print() => Console.WriteLine("Scanning to PDF...");
}
  • 方法為介面專用,非類別核心功能:如 IDisposable.Dispose、IEnumerable.GetEnumerator、IComparable.CompareTo — 避免汙染類別公用 API。
  • 隱藏實作細節:強制消費者透過介面程式設計,降低耦合。
  • 避免命名衝突:類別已有同名方法但語意不同。

🎯 實務建議:預設顯式,必要時隱式

現代 C# 開發傾向:**介面方法預設顯式實作**,除非該方法確實屬於類別的公用合約一部分。這能:

  1. 保持類別公用 API 乾淨
  2. 明確表達「此方法屬於介面契約」
  3. 避免未來介面變更波及類別消費者
  4. 配合依賴注入 (DI) 容器,消費者本就持有介面參考

進階:重新實作與密封行為


interface IBase { void Do(); }

class Base : IBase {
    void IBase.Do() { Console.WriteLine("Base"); } // 顯式實作 = 密封
}

class Derived : Base, IBase {
    // 無法 override Base 的顯式實作
    // 但可「重新實作」介面方法 (隱藏基類實作)
    void IBase.Do() { Console.WriteLine("Derived"); } // 新的介面實作
    
    // 或隱式實作 (公開給類別實例)
    public void Do() { Console.WriteLine("Derived Public"); }
}

IBase obj = new Derived();
obj.Do(); // 輸出 "Derived" (最衍生類的介面實作優先)

C# 8+ 預設介面方法與顯式實作互動


interface ILogger {
    void Log(string msg) => Console.WriteLine($"[DEFAULT] {msg}"); // 預設實作
}

class MyLogger : ILogger {
    // 顯式實作:無法呼叫 base.Log(),必須完整實作
    void ILogger.Log(string msg) => Console.WriteLine($"[CUSTOM] {msg}");
    
    // 隱式實作:可選擇覆寫或繼承預設
    // public void Log(string msg) => ... // 若寫這行,類別實例可見
}

ILogger logger = new MyLogger();
logger.Log("Test"); // [CUSTOM] Test

快速判斷清單


需要實作介面方法
    │
    ├─ 多個介面有同名方法? → 必須顯式實作 (分別實作)
    │
    ├─ 方法為基礎設施介面 (IDisposable, IEnumerable, IComparable...)? → 顯式實作
    │
    ├─ 方法語意屬於類別核心公用 API? → 隱式實作 (public)
    │
    ├─ 需要 virtual/override 多型? → 隱式實作
    │
    ├─ 希望強制消費者用介面參考? → 顯式實作
    │
    └─ 不確定? → 顯式實作 (較安全、較解耦)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved