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

C# 多重實作模式:以介面取代多重繼承的設計指南

     編輯:關於C語言

前言:C# 不支援多重繼承,該怎麼辦?

C# 為單一繼承語言,一個類別只能繼承一個基底類別。但現實領域模型常需組合多種行為(如「卡車」同時具備「車輛」與「工程車輛」特性)。本文探討如何透過多重介面實作與顯式介面實作,優雅解決此設計難題。

情境建模:從車輛到傾卸卡車

傳統繼承嘗試(失敗)

abstract class Vehicle { public abstract void Accelerate(); public abstract void Stop(); }
class ConstructionVehicle { public void ExecuteDump() {} public void TurnOnBackUpSound() {} }

// 無法同時繼承 Vehicle 與 ConstructionVehicle

介面導向重構

interface IVehicle
{
    void Accelerate();
    void Stop();
    void TurnOnBackUpSound(); // 共同方法
}

interface IConstructionVehicle
{
    void ExecuteDump();
    void TurnOnBackUpSound(); // 同名方法
}

顯式介面實作:解決同名衝突

當多個介面擁有相同簽章方法時,類別可透過介面名稱限定分別實作:

public class DumpTruck : IVehicle, IConstructionVehicle
{
    // IVehicle 版本
    void IVehicle.TurnOnBackUpSound()
    {
        Console.WriteLine("[車輛] 倒車警報:哔哔~");
    }

    // IConstructionVehicle 版本
    void IConstructionVehicle.TurnOnBackUpSound()
    {
        Console.WriteLine("[工程車] 倒車警報:轟隆+哔哔~");
    }

    public void Accelerate() => Console.WriteLine("加速中...");
    public void Stop() => Console.WriteLine("煞車停止");
    public void ExecuteDump() => Console.WriteLine("貨箱傾卸中...");
}

呼叫方式

var truck = new DumpTruck();
truck.Accelerate(); // 直接呼叫

// 需轉型至介面才能呼叫顯式實作
((IVehicle)truck).TurnOnBackUpSound();      // 輸出:[車輛] 倒車警報:哔哔~
((IConstructionVehicle)truck).TurnOnBackUpSound(); // 輸出:[工程車] 倒車警報:轟隆+哔哔~

實作隱藏:減少介面汙染

顯式實作的方法不會出現在類別的公用介面中,僅能透過介面參考存取,優點:

  • 避免 IntelliSense 雜訊,開發者不易誤呼叫
  • 強制呼叫端明確指定語意(車輛 vs 工程車)
  • 符合介面隔離原則 (ISP)

進階模式:組合優於繼承

策略模式注入行為

interface IBackupSoundStrategy { void Play(); }

class VehicleBackupSound : IBackupSoundStrategy { public void Play() => Console.WriteLine("哔哔"); }
class ConstructionBackupSound : IBackupSoundStrategy { public void Play() => Console.WriteLine("轟隆+哔哔"); }

class SmartDumpTruck
{
    private readonly IBackupSoundStrategy _sound;
    public SmartDumpTruck(IBackupSoundStrategy sound) => _sound = sound;
    public void TurnOnBackUpSound() => _sound.Play();
}

// 使用
var truck1 = new SmartDumpTruck(new VehicleBackupSound());
var truck2 = new SmartDumpTruck(new ConstructionBackupSound());

預設介面方法 (C# 8.0+)

interface IVehicle
{
    void Accelerate();
    void Stop();
    void TurnOnBackUpSound() => Console.WriteLine("預設車輛倒車音"); // 預設實作
}

interface IConstructionVehicle
{
    void ExecuteDump();
    void TurnOnBackUpSound() => Console.WriteLine("預設工程車倒車音");
}

class ModernDumpTruck : IVehicle, IConstructionVehicle
{
    public void Accelerate() => Console.WriteLine("電動加速");
    public void Stop() => Console.WriteLine("再生煞車");
    public void ExecuteDump() => Console.WriteLine("液壓傾卸");

    // 明確選擇或覆寫
    void IVehicle.TurnOnBackUpSound() => IVehicle.DefaultTurnOnBackUpSound(); // 呼叫預設
}

設計決策對照表

情境建議方案關鍵字
單一繼承足夠基底類別 + 虛擬方法abstract, virtual, override
需組合多種獨立行為多重介面實作interface, explicit implementation
介面方法同名衝突顯式介面實作InterfaceName.Method()
行為需動態切換策略模式 / 委派注入Func<T>, Strategy Pattern
提供預設行為供選擇性覆寫預設介面方法 (C# 8+)default interface method

總結

C# 以「單一繼承 + 多重介面實作」取代 C++ 風格的多重繼承,配合顯式介面實作解決同名衝突,並提供實作隱藏降低耦合。現代 C# (8.0+) 更引入預設介面方法,讓介面演進不再破壞現有實作。掌握這些模式,即能設計出彈性、可維護的物件導向架構。

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