Skip to content

C# 接口

本章将详细介绍 C# 中的接口,包括接口的定义、实现、多接口实现、接口继承等概念,帮助你设计更灵活和可扩展的程序架构。

接口的基本概念

什么是接口

csharp
// 接口定义了一组方法、属性、事件或索引器的签名
// 接口不包含实现,只定义契约

// 基本接口定义
public interface IDrawable
{
    // 方法签名(无实现)
    void Draw();
    void Move(int x, int y);
    
    // 属性签名
    bool IsVisible { get; set; }
    string Name { get; }
    
    // 只读属性
    DateTime CreatedTime { get; }
}

// 接口实现
public class Circle : IDrawable
{
    private int x, y, radius;
    private bool isVisible;
    private string name;
    private DateTime createdTime;
    
    public Circle(string name, int x, int y, int radius)
    {
        this.name = name;
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.isVisible = true;
        this.createdTime = DateTime.Now;
    }
    
    // 实现接口方法
    public void Draw()
    {
        if (isVisible)
        {
            Console.WriteLine($"绘制圆形 {name} 在位置 ({x}, {y}),半径 {radius}");
        }
    }
    
    public void Move(int newX, int newY)
    {
        x = newX;
        y = newY;
        Console.WriteLine($"圆形 {name} 移动到 ({x}, {y})");
    }
    
    // 实现接口属性
    public bool IsVisible
    {
        get => isVisible;
        set
        {
            isVisible = value;
            Console.WriteLine($"圆形 {name} 可见性设置为: {isVisible}");
        }
    }
    
    public string Name => name;
    public DateTime CreatedTime => createdTime;
    
    // 类的其他成员
    public int Radius => radius;
    
    public double CalculateArea()
    {
        return Math.PI * radius * radius;
    }
}

public class Rectangle : IDrawable
{
    private int x, y, width, height;
    private bool isVisible;
    private string name;
    private DateTime createdTime;
    
    public Rectangle(string name, int x, int y, int width, int height)
    {
        this.name = name;
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.isVisible = true;
        this.createdTime = DateTime.Now;
    }
    
    public void Draw()
    {
        if (isVisible)
        {
            Console.WriteLine($"绘制矩形 {name} 在位置 ({x}, {y}),大小 {width}x{height}");
        }
    }
    
    public void Move(int newX, int newY)
    {
        x = newX;
        y = newY;
        Console.WriteLine($"矩形 {name} 移动到 ({x}, {y})");
    }
    
    public bool IsVisible
    {
        get => isVisible;
        set
        {
            isVisible = value;
            Console.WriteLine($"矩形 {name} 可见性设置为: {isVisible}");
        }
    }
    
    public string Name => name;
    public DateTime CreatedTime => createdTime;
    
    public int Width => width;
    public int Height => height;
    
    public double CalculateArea()
    {
        return width * height;
    }
}

static void BasicInterfaceDemo()
{
    Console.WriteLine("=== 基本接口演示 ===");
    
    // 使用接口引用
    IDrawable[] shapes = {
        new Circle("圆1", 10, 10, 5),
        new Rectangle("矩形1", 20, 20, 8, 6),
        new Circle("圆2", 30, 30, 3)
    };
    
    // 多态操作
    foreach (IDrawable shape in shapes)
    {
        Console.WriteLine($"形状: {shape.Name}, 创建时间: {shape.CreatedTime:HH:mm:ss}");
        shape.Draw();
        shape.Move(shape.Name.Contains("圆") ? 50 : 60, 50);
        Console.WriteLine();
    }
    
    // 隐藏部分形状
    Console.WriteLine("隐藏第一个形状:");
    shapes[0].IsVisible = false;
    shapes[0].Draw();  // 不会绘制
}

接口 vs 抽象类

csharp
// 抽象类 - 可以包含实现
public abstract class Shape
{
    protected string name;
    protected DateTime createdTime;
    
    public Shape(string name)
    {
        this.name = name;
        this.createdTime = DateTime.Now;
    }
    
    // 具体实现
    public string Name => name;
    public DateTime CreatedTime => createdTime;
    
    // 抽象方法 - 必须实现
    public abstract double CalculateArea();
    public abstract void Draw();
    
    // 虚方法 - 可以重写
    public virtual void DisplayInfo()
    {
        Console.WriteLine($"形状: {name}, 面积: {CalculateArea():F2}");
    }
}

// 接口 - 只定义契约
public interface IMovable
{
    void Move(int deltaX, int deltaY);
    int X { get; }
    int Y { get; }
}

public interface IResizable
{
    void Resize(double factor);
    double GetArea();
}

// 类可以继承一个抽象类并实现多个接口
public class SmartCircle : Shape, IMovable, IResizable
{
    private int x, y;
    private double radius;
    
    public SmartCircle(string name, int x, int y, double radius) : base(name)
    {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }
    
    // 实现抽象类的抽象方法
    public override double CalculateArea()
    {
        return Math.PI * radius * radius;
    }
    
    public override void Draw()
    {
        Console.WriteLine($"绘制智能圆形 {name} 在 ({x}, {y}),半径 {radius}");
    }
    
    // 实现 IMovable 接口
    public void Move(int deltaX, int deltaY)
    {
        x += deltaX;
        y += deltaY;
        Console.WriteLine($"圆形 {name} 移动了 ({deltaX}, {deltaY}),新位置 ({x}, {y})");
    }
    
    public int X => x;
    public int Y => y;
    
    // 实现 IResizable 接口
    public void Resize(double factor)
    {
        radius *= factor;
        Console.WriteLine($"圆形 {name} 缩放 {factor}倍,新半径 {radius:F2}");
    }
    
    public double GetArea()
    {
        return CalculateArea();
    }
    
    // 重写虚方法
    public override void DisplayInfo()
    {
        base.DisplayInfo();
        Console.WriteLine($"位置: ({x}, {y}), 半径: {radius:F2}");
    }
}

static void InterfaceVsAbstractDemo()
{
    Console.WriteLine("=== 接口 vs 抽象类演示 ===");
    
    SmartCircle circle = new SmartCircle("智能圆", 0, 0, 5.0);
    
    // 作为抽象类使用
    Shape shape = circle;
    shape.DisplayInfo();
    
    // 作为 IMovable 接口使用
    IMovable movable = circle;
    movable.Move(10, 15);
    Console.WriteLine($"当前位置: ({movable.X}, {movable.Y})");
    
    // 作为 IResizable 接口使用
    IResizable resizable = circle;
    Console.WriteLine($"调整前面积: {resizable.GetArea():F2}");
    resizable.Resize(1.5);
    Console.WriteLine($"调整后面积: {resizable.GetArea():F2}");
    
    Console.WriteLine("\n最终状态:");
    circle.DisplayInfo();
}

多接口实现

实现多个接口

csharp
// 定义多个相关接口
public interface IReadable
{
    string Read();
    bool CanRead { get; }
}

public interface IWritable
{
    void Write(string content);
    bool CanWrite { get; }
}

public interface ISeekable
{
    void Seek(long position);
    long Position { get; }
    long Length { get; }
}

public interface ICloseable
{
    void Close();
    bool IsClosed { get; }
}

// 实现多个接口的文件类
public class TextFile : IReadable, IWritable, ISeekable, ICloseable
{
    private string fileName;
    private List<string> lines;
    private long position;
    private bool isClosed;
    private bool canRead;
    private bool canWrite;
    
    public TextFile(string fileName, bool readOnly = false)
    {
        this.fileName = fileName;
        this.lines = new List<string>();
        this.position = 0;
        this.isClosed = false;
        this.canRead = true;
        this.canWrite = !readOnly;
        
        // 模拟加载文件内容
        LoadFile();
    }
    
    private void LoadFile()
    {
        lines.Add($"这是文件 {fileName} 的第一行内容");
        lines.Add($"这是文件 {fileName} 的第二行内容");
        lines.Add($"这是文件 {fileName} 的第三行内容");
        Console.WriteLine($"加载文件: {fileName}");
    }
    
    // IReadable 实现
    public string Read()
    {
        if (!CanRead)
            throw new InvalidOperationException("文件不可读");
            
        if (position >= lines.Count)
            return null;
            
        string line = lines[(int)position];
        position++;
        return line;
    }
    
    public bool CanRead => canRead && !isClosed;
    
    // IWritable 实现
    public void Write(string content)
    {
        if (!CanWrite)
            throw new InvalidOperationException("文件不可写");
            
        lines.Add(content);
        Console.WriteLine($"写入内容到 {fileName}: {content}");
    }
    
    public bool CanWrite => canWrite && !isClosed;
    
    // ISeekable 实现
    public void Seek(long newPosition)
    {
        if (newPosition < 0 || newPosition > lines.Count)
            throw new ArgumentOutOfRangeException(nameof(newPosition));
            
        position = newPosition;
        Console.WriteLine($"文件 {fileName} 定位到位置: {position}");
    }
    
    public long Position => position;
    public long Length => lines.Count;
    
    // ICloseable 实现
    public void Close()
    {
        if (!isClosed)
        {
            isClosed = true;
            Console.WriteLine($"关闭文件: {fileName}");
        }
    }
    
    public bool IsClosed => isClosed;
    
    // 额外的方法
    public void DisplayContent()
    {
        Console.WriteLine($"\n=== {fileName} 内容 ===");
        for (int i = 0; i < lines.Count; i++)
        {
            string marker = (i == position) ? ">>> " : "    ";
            Console.WriteLine($"{marker}{i}: {lines[i]}");
        }
        Console.WriteLine($"当前位置: {position}, 总行数: {Length}");
    }
}

// 网络流类
public class NetworkStream : IReadable, IWritable, ICloseable
{
    private string endpoint;
    private bool isConnected;
    private Queue<string> incomingData;
    private bool isClosed;
    
    public NetworkStream(string endpoint)
    {
        this.endpoint = endpoint;
        this.isConnected = true;
        this.incomingData = new Queue<string>();
        this.isClosed = false;
        
        // 模拟接收数据
        SimulateIncomingData();
        Console.WriteLine($"连接到网络端点: {endpoint}");
    }
    
    private void SimulateIncomingData()
    {
        incomingData.Enqueue("网络数据包 1");
        incomingData.Enqueue("网络数据包 2");
        incomingData.Enqueue("网络数据包 3");
    }
    
    public string Read()
    {
        if (!CanRead)
            throw new InvalidOperationException("网络流不可读");
            
        if (incomingData.Count == 0)
            return null;
            
        string data = incomingData.Dequeue();
        Console.WriteLine($"从 {endpoint} 读取: {data}");
        return data;
    }
    
    public bool CanRead => isConnected && !isClosed;
    
    public void Write(string content)
    {
        if (!CanWrite)
            throw new InvalidOperationException("网络流不可写");
            
        Console.WriteLine($"向 {endpoint} 发送: {content}");
    }
    
    public bool CanWrite => isConnected && !isClosed;
    
    public void Close()
    {
        if (!isClosed)
        {
            isConnected = false;
            isClosed = true;
            Console.WriteLine($"关闭网络连接: {endpoint}");
        }
    }
    
    public bool IsClosed => isClosed;
}

// 使用多接口的工具类
public class StreamProcessor
{
    public static void ProcessReadableStream(IReadable readable)
    {
        Console.WriteLine("处理可读流:");
        string data;
        while ((data = readable.Read()) != null)
        {
            Console.WriteLine($"  处理数据: {data}");
        }
    }
    
    public static void WriteToStream(IWritable writable, string[] contents)
    {
        Console.WriteLine("写入数据到流:");
        foreach (string content in contents)
        {
            writable.Write(content);
        }
    }
    
    public static void CopyStream(IReadable source, IWritable destination)
    {
        Console.WriteLine("复制流数据:");
        string data;
        while ((data = source.Read()) != null)
        {
            destination.Write($"复制: {data}");
        }
    }
}

static void MultipleInterfaceDemo()
{
    Console.WriteLine("=== 多接口实现演示 ===");
    
    // 创建不同类型的流
    TextFile textFile = new TextFile("document.txt");
    NetworkStream networkStream = new NetworkStream("192.168.1.100:8080");
    
    // 显示文件内容
    textFile.DisplayContent();
    
    // 使用接口进行多态操作
    Console.WriteLine("\n1. 读取操作:");
    StreamProcessor.ProcessReadableStream(textFile);
    
    Console.WriteLine("\n2. 写入操作:");
    string[] newContent = { "新增行1", "新增行2" };
    StreamProcessor.WriteToStream(textFile, newContent);
    
    textFile.DisplayContent();
    
    Console.WriteLine("\n3. 网络流操作:");
    StreamProcessor.ProcessReadableStream(networkStream);
    StreamProcessor.WriteToStream(networkStream, new[] { "Hello Server" });
    
    Console.WriteLine("\n4. 流复制:");
    textFile.Seek(0);  // 重置到开始位置
    StreamProcessor.CopyStream(textFile, networkStream);
    
    // 关闭资源
    Console.WriteLine("\n5. 关闭资源:");
    textFile.Close();
    networkStream.Close();
}

接口的显式实现

csharp
// 当实现多个接口时,可能出现成员名称冲突
public interface IPrinter
{
    void Print();
    string Status { get; }
}

public interface IScanner
{
    void Print();  // 与 IPrinter.Print() 冲突
    string Status { get; }  // 与 IPrinter.Status 冲突
}

public interface IFax
{
    void Send(string number, string content);
    string Status { get; }
}

// 使用显式接口实现解决冲突
public class MultiFunctionDevice : IPrinter, IScanner, IFax
{
    private string deviceName;
    private bool isPrinterReady;
    private bool isScannerReady;
    private bool isFaxReady;
    
    public MultiFunctionDevice(string deviceName)
    {
        this.deviceName = deviceName;
        this.isPrinterReady = true;
        this.isScannerReady = true;
        this.isFaxReady = true;
    }
    
    // IPrinter 显式实现
    void IPrinter.Print()
    {
        Console.WriteLine($"{deviceName}: 打印文档");
    }
    
    string IPrinter.Status => isPrinterReady ? "打印机就绪" : "打印机故障";
    
    // IScanner 显式实现
    void IScanner.Print()
    {
        Console.WriteLine($"{deviceName}: 扫描文档");
    }
    
    string IScanner.Status => isScannerReady ? "扫描仪就绪" : "扫描仪故障";
    
    // IFax 显式实现
    void IFax.Send(string number, string content)
    {
        Console.WriteLine($"{deviceName}: 发送传真到 {number}: {content}");
    }
    
    string IFax.Status => isFaxReady ? "传真机就绪" : "传真机故障";
    
    // 公共方法
    public void ShowAllStatus()
    {
        IPrinter printer = this;
        IScanner scanner = this;
        IFax fax = this;
        
        Console.WriteLine($"设备: {deviceName}");
        Console.WriteLine($"  打印机状态: {printer.Status}");
        Console.WriteLine($"  扫描仪状态: {scanner.Status}");
        Console.WriteLine($"  传真机状态: {fax.Status}");
    }
    
    public void SetPrinterStatus(bool ready)
    {
        isPrinterReady = ready;
    }
    
    public void SetScannerStatus(bool ready)
    {
        isScannerReady = ready;
    }
    
    public void SetFaxStatus(bool ready)
    {
        isFaxReady = ready;
    }
}

static void ExplicitInterfaceDemo()
{
    Console.WriteLine("=== 显式接口实现演示 ===");
    
    MultiFunctionDevice device = new MultiFunctionDevice("HP LaserJet Pro");
    
    // 显示所有状态
    device.ShowAllStatus();
    
    // 使用显式接口实现
    IPrinter printer = device;
    IScanner scanner = device;
    IFax fax = device;
    
    Console.WriteLine("\n执行不同功能:");
    printer.Print();  // 调用打印功能
    scanner.Print();  // 调用扫描功能
    fax.Send("123-456-7890", "重要文档");
    
    // 模拟设备故障
    Console.WriteLine("\n模拟设备故障:");
    device.SetPrinterStatus(false);
    device.SetScannerStatus(false);
    device.ShowAllStatus();
    
    // 无法直接调用显式实现的成员
    // device.Print();  // 编译错误:不明确的调用
    
    // 必须通过接口引用调用
    Console.WriteLine("\n通过接口调用:");
    Console.WriteLine($"打印机: {printer.Status}");
    Console.WriteLine($"扫描仪: {scanner.Status}");
}

接口继承

接口的继承关系

csharp
// 基础接口
public interface IShape
{
    string Name { get; }
    double CalculateArea();
    void Display();
}

// 继承接口 - 添加新成员
public interface IColoredShape : IShape
{
    ConsoleColor Color { get; set; }
    void ChangeColor(ConsoleColor newColor);
}

public interface IMovableShape : IShape
{
    int X { get; }
    int Y { get; }
    void MoveTo(int x, int y);
    void MoveBy(int deltaX, int deltaY);
}

// 多重接口继承
public interface IAdvancedShape : IColoredShape, IMovableShape
{
    void Rotate(double angle);
    void Scale(double factor);
    bool IsSelected { get; set; }
}

// 实现继承接口的类
public class AdvancedCircle : IAdvancedShape
{
    private string name;
    private double radius;
    private int x, y;
    private ConsoleColor color;
    private bool isSelected;
    private double rotation;
    
    public AdvancedCircle(string name, double radius, int x, int y, ConsoleColor color = ConsoleColor.White)
    {
        this.name = name;
        this.radius = radius;
        this.x = x;
        this.y = y;
        this.color = color;
        this.isSelected = false;
        this.rotation = 0;
    }
    
    // IShape 实现
    public string Name => name;
    
    public double CalculateArea()
    {
        return Math.PI * radius * radius;
    }
    
    public void Display()
    {
        Console.ForegroundColor = color;
        string selectedMark = isSelected ? "[选中] " : "";
        Console.WriteLine($"{selectedMark}圆形 {name}: 位置({x}, {y}), 半径{radius}, 旋转{rotation}°");
        Console.ResetColor();
    }
    
    // IColoredShape 实现
    public ConsoleColor Color
    {
        get => color;
        set
        {
            color = value;
            Console.WriteLine($"圆形 {name} 颜色改为: {color}");
        }
    }
    
    public void ChangeColor(ConsoleColor newColor)
    {
        Color = newColor;
    }
    
    // IMovableShape 实现
    public int X => x;
    public int Y => y;
    
    public void MoveTo(int newX, int newY)
    {
        x = newX;
        y = newY;
        Console.WriteLine($"圆形 {name} 移动到: ({x}, {y})");
    }
    
    public void MoveBy(int deltaX, int deltaY)
    {
        x += deltaX;
        y += deltaY;
        Console.WriteLine($"圆形 {name} 移动了: ({deltaX}, {deltaY}), 新位置: ({x}, {y})");
    }
    
    // IAdvancedShape 实现
    public void Rotate(double angle)
    {
        rotation = (rotation + angle) % 360;
        Console.WriteLine($"圆形 {name} 旋转 {angle}°, 当前角度: {rotation}°");
    }
    
    public void Scale(double factor)
    {
        radius *= factor;
        Console.WriteLine($"圆形 {name} 缩放 {factor}倍, 新半径: {radius:F2}");
    }
    
    public bool IsSelected
    {
        get => isSelected;
        set
        {
            isSelected = value;
            Console.WriteLine($"圆形 {name} {(isSelected ? "已选中" : "取消选中")}");
        }
    }
}

// 图形编辑器类
public class GraphicsEditor
{
    private List<IAdvancedShape> shapes;
    private List<IAdvancedShape> selectedShapes;
    
    public GraphicsEditor()
    {
        shapes = new List<IAdvancedShape>();
        selectedShapes = new List<IAdvancedShape>();
    }
    
    public void AddShape(IAdvancedShape shape)
    {
        shapes.Add(shape);
        Console.WriteLine($"添加形状: {shape.Name}");
    }
    
    public void SelectShape(string name)
    {
        var shape = shapes.FirstOrDefault(s => s.Name == name);
        if (shape != null && !shape.IsSelected)
        {
            shape.IsSelected = true;
            selectedShapes.Add(shape);
        }
    }
    
    public void DeselectShape(string name)
    {
        var shape = selectedShapes.FirstOrDefault(s => s.Name == name);
        if (shape != null)
        {
            shape.IsSelected = false;
            selectedShapes.Remove(shape);
        }
    }
    
    public void MoveSelectedShapes(int deltaX, int deltaY)
    {
        Console.WriteLine($"移动选中的形状 ({deltaX}, {deltaY}):");
        foreach (var shape in selectedShapes)
        {
            shape.MoveBy(deltaX, deltaY);
        }
    }
    
    public void RotateSelectedShapes(double angle)
    {
        Console.WriteLine($"旋转选中的形状 {angle}°:");
        foreach (var shape in selectedShapes)
        {
            shape.Rotate(angle);
        }
    }
    
    public void ChangeSelectedShapesColor(ConsoleColor color)
    {
        Console.WriteLine($"改变选中形状的颜色为 {color}:");
        foreach (var shape in selectedShapes)
        {
            shape.ChangeColor(color);
        }
    }
    
    public void DisplayAllShapes()
    {
        Console.WriteLine("\n=== 所有形状 ===");
        foreach (var shape in shapes)
        {
            shape.Display();
        }
    }
    
    public void ShowStatistics()
    {
        Console.WriteLine($"\n=== 统计信息 ===");
        Console.WriteLine($"总形状数: {shapes.Count}");
        Console.WriteLine($"选中形状数: {selectedShapes.Count}");
        
        double totalArea = shapes.Sum(s => s.CalculateArea());
        Console.WriteLine($"总面积: {totalArea:F2}");
        
        if (selectedShapes.Count > 0)
        {
            double selectedArea = selectedShapes.Sum(s => s.CalculateArea());
            Console.WriteLine($"选中形状面积: {selectedArea:F2}");
        }
    }
}

static void InterfaceInheritanceDemo()
{
    Console.WriteLine("=== 接口继承演示 ===");
    
    GraphicsEditor editor = new GraphicsEditor();
    
    // 添加形状
    editor.AddShape(new AdvancedCircle("圆1", 5.0, 10, 10, ConsoleColor.Red));
    editor.AddShape(new AdvancedCircle("圆2", 3.0, 20, 20, ConsoleColor.Blue));
    editor.AddShape(new AdvancedCircle("圆3", 4.0, 30, 30, ConsoleColor.Green));
    
    // 显示所有形状
    editor.DisplayAllShapes();
    editor.ShowStatistics();
    
    // 选择形状
    Console.WriteLine("\n=== 选择和操作形状 ===");
    editor.SelectShape("圆1");
    editor.SelectShape("圆3");
    
    // 操作选中的形状
    editor.MoveSelectedShapes(5, 5);
    editor.RotateSelectedShapes(45);
    editor.ChangeSelectedShapesColor(ConsoleColor.Yellow);
    
    // 显示最终结果
    editor.DisplayAllShapes();
    editor.ShowStatistics();
}

实践示例

示例 1:插件系统

csharp
using System;
using System.Collections.Generic;
using System.Reflection;

// 插件基础接口
public interface IPlugin
{
    string Name { get; }
    string Version { get; }
    string Description { get; }
    bool IsEnabled { get; set; }
    void Initialize();
    void Execute();
    void Cleanup();
}

// 可配置插件接口
public interface IConfigurablePlugin : IPlugin
{
    Dictionary<string, object> GetConfiguration();
    void SetConfiguration(Dictionary<string, object> config);
    void ShowConfigurationDialog();
}

// 数据处理插件接口
public interface IDataProcessor : IPlugin
{
    bool CanProcess(string dataType);
    object ProcessData(object input);
    string[] SupportedDataTypes { get; }
}

// 用户界面插件接口
public interface IUIPlugin : IPlugin
{
    void ShowUI();
    void HideUI();
    bool IsUIVisible { get; }
}

// 文本处理插件
public class TextProcessorPlugin : IDataProcessor, IConfigurablePlugin
{
    private bool isEnabled;
    private Dictionary<string, object> configuration;
    private bool isInitialized;
    
    public TextProcessorPlugin()
    {
        isEnabled = true;
        configuration = new Dictionary<string, object>
        {
            ["MaxLength"] = 1000,
            ["RemoveSpaces"] = false,
            ["ConvertToUpper"] = false
        };
        isInitialized = false;
    }
    
    // IPlugin 实现
    public string Name => "文本处理器";
    public string Version => "1.0.0";
    public string Description => "提供文本处理功能,包括格式化、转换等";
    
    public bool IsEnabled
    {
        get => isEnabled;
        set
        {
            isEnabled = value;
            Console.WriteLine($"文本处理器插件 {(isEnabled ? "启用" : "禁用")}");
        }
    }
    
    public void Initialize()
    {
        if (!isInitialized)
        {
            Console.WriteLine("初始化文本处理器插件...");
            isInitialized = true;
        }
    }
    
    public void Execute()
    {
        if (!isEnabled || !isInitialized)
        {
            Console.WriteLine("文本处理器插件未启用或未初始化");
            return;
        }
        
        Console.WriteLine("执行文本处理器插件");
    }
    
    public void Cleanup()
    {
        Console.WriteLine("清理文本处理器插件资源");
        isInitialized = false;
    }
    
    // IDataProcessor 实现
    public bool CanProcess(string dataType)
    {
        return SupportedDataTypes.Contains(dataType.ToLower());
    }
    
    public object ProcessData(object input)
    {
        if (input is string text)
        {
            string result = text;
            
            // 应用配置
            int maxLength = (int)configuration["MaxLength"];
            bool removeSpaces = (bool)configuration["RemoveSpaces"];
            bool convertToUpper = (bool)configuration["ConvertToUpper"];
            
            if (result.Length > maxLength)
            {
                result = result.Substring(0, maxLength) + "...";
            }
            
            if (removeSpaces)
            {
                result = result.Replace(" ", "");
            }
            
            if (convertToUpper)
            {
                result = result.ToUpper();
            }
            
            Console.WriteLine($"文本处理: '{text}' -> '{result}'");
            return result;
        }
        
        throw new ArgumentException("不支持的数据类型");
    }
    
    public string[] SupportedDataTypes => new[] { "text", "string" };
    
    // IConfigurablePlugin 实现
    public Dictionary<string, object> GetConfiguration()
    {
        return new Dictionary<string, object>(configuration);
    }
    
    public void SetConfiguration(Dictionary<string, object> config)
    {
        foreach (var kvp in config)
        {
            if (configuration.ContainsKey(kvp.Key))
            {
                configuration[kvp.Key] = kvp.Value;
                Console.WriteLine($"配置更新: {kvp.Key} = {kvp.Value}");
            }
        }
    }
    
    public void ShowConfigurationDialog()
    {
        Console.WriteLine("=== 文本处理器配置 ===");
        foreach (var kvp in configuration)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }
}

// 图像查看器插件
public class ImageViewerPlugin : IUIPlugin, IDataProcessor
{
    private bool isEnabled;
    private bool isUIVisible;
    private bool isInitialized;
    
    public ImageViewerPlugin()
    {
        isEnabled = true;
        isUIVisible = false;
        isInitialized = false;
    }
    
    // IPlugin 实现
    public string Name => "图像查看器";
    public string Version => "2.1.0";
    public string Description => "显示和处理图像文件";
    
    public bool IsEnabled
    {
        get => isEnabled;
        set
        {
            isEnabled = value;
            if (!isEnabled && isUIVisible)
            {
                HideUI();
            }
        }
    }
    
    public void Initialize()
    {
        if (!isInitialized)
        {
            Console.WriteLine("初始化图像查看器插件...");
            isInitialized = true;
        }
    }
    
    public void Execute()
    {
        if (isEnabled && isInitialized)
        {
            ShowUI();
        }
    }
    
    public void Cleanup()
    {
        HideUI();
        Console.WriteLine("清理图像查看器插件资源");
        isInitialized = false;
    }
    
    // IUIPlugin 实现
    public void ShowUI()
    {
        if (!isUIVisible)
        {
            isUIVisible = true;
            Console.WriteLine("显示图像查看器界面");
        }
    }
    
    public void HideUI()
    {
        if (isUIVisible)
        {
            isUIVisible = false;
            Console.WriteLine("隐藏图像查看器界面");
        }
    }
    
    public bool IsUIVisible => isUIVisible;
    
    // IDataProcessor 实现
    public bool CanProcess(string dataType)
    {
        return SupportedDataTypes.Contains(dataType.ToLower());
    }
    
    public object ProcessData(object input)
    {
        if (input is string imagePath)
        {
            Console.WriteLine($"加载图像: {imagePath}");
            return $"已处理的图像: {imagePath}";
        }
        
        throw new ArgumentException("需要图像文件路径");
    }
    
    public string[] SupportedDataTypes => new[] { "image", "jpg", "png", "gif", "bmp" };
}

// 插件管理器
public class PluginManager
{
    private List<IPlugin> plugins;
    private Dictionary<string, IPlugin> pluginsByName;
    
    public PluginManager()
    {
        plugins = new List<IPlugin>();
        pluginsByName = new Dictionary<string, IPlugin>();
    }
    
    public void RegisterPlugin(IPlugin plugin)
    {
        plugins.Add(plugin);
        pluginsByName[plugin.Name] = plugin;
        Console.WriteLine($"注册插件: {plugin.Name} v{plugin.Version}");
    }
    
    public void InitializeAllPlugins()
    {
        Console.WriteLine("初始化所有插件...");
        foreach (var plugin in plugins)
        {
            if (plugin.IsEnabled)
            {
                plugin.Initialize();
            }
        }
    }
    
    public void ExecutePlugin(string name)
    {
        if (pluginsByName.TryGetValue(name, out IPlugin plugin))
        {
            plugin.Execute();
        }
        else
        {
            Console.WriteLine($"未找到插件: {name}");
        }
    }
    
    public void ProcessDataWithPlugins(object data, string dataType)
    {
        Console.WriteLine($"处理数据类型: {dataType}");
        
        foreach (var plugin in plugins)
        {
            if (plugin is IDataProcessor processor && processor.CanProcess(dataType))
            {
                try
                {
                    var result = processor.ProcessData(data);
                    Console.WriteLine($"插件 {plugin.Name} 处理完成");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"插件 {plugin.Name} 处理失败: {ex.Message}");
                }
            }
        }
    }
    
    public void ShowAllPluginConfigurations()
    {
        Console.WriteLine("\n=== 所有插件配置 ===");
        foreach (var plugin in plugins)
        {
            if (plugin is IConfigurablePlugin configurable)
            {
                Console.WriteLine($"\n{plugin.Name} 配置:");
                configurable.ShowConfigurationDialog();
            }
        }
    }
    
    public void ShowPluginStatistics()
    {
        Console.WriteLine("\n=== 插件统计 ===");
        Console.WriteLine($"总插件数: {plugins.Count}");
        Console.WriteLine($"启用插件数: {plugins.Count(p => p.IsEnabled)}");
        
        int dataProcessors = plugins.Count(p => p is IDataProcessor);
        int uiPlugins = plugins.Count(p => p is IUIPlugin);
        int configurablePlugins = plugins.Count(p => p is IConfigurablePlugin);
        
        Console.WriteLine($"数据处理插件: {dataProcessors}");
        Console.WriteLine($"UI插件: {uiPlugins}");
        Console.WriteLine($"可配置插件: {configurablePlugins}");
        
        Console.WriteLine("\n插件列表:");
        foreach (var plugin in plugins)
        {
            string status = plugin.IsEnabled ? "启用" : "禁用";
            Console.WriteLine($"  {plugin.Name} v{plugin.Version} [{status}]");
            Console.WriteLine($"    {plugin.Description}");
        }
    }
    
    public void CleanupAllPlugins()
    {
        Console.WriteLine("清理所有插件...");
        foreach (var plugin in plugins)
        {
            plugin.Cleanup();
        }
    }
}

static void PluginSystemDemo()
{
    Console.WriteLine("=== 插件系统演示 ===");
    
    PluginManager manager = new PluginManager();
    
    // 注册插件
    manager.RegisterPlugin(new TextProcessorPlugin());
    manager.RegisterPlugin(new ImageViewerPlugin());
    
    // 初始化插件
    manager.InitializeAllPlugins();
    
    // 显示插件统计
    manager.ShowPluginStatistics();
    
    // 执行插件
    Console.WriteLine("\n=== 执行插件 ===");
    manager.ExecutePlugin("文本处理器");
    manager.ExecutePlugin("图像查看器");
    
    // 处理数据
    Console.WriteLine("\n=== 数据处理 ===");
    manager.ProcessDataWithPlugins("Hello World! This is a long text that might be truncated.", "text");
    manager.ProcessDataWithPlugins("image.jpg", "image");
    
    // 显示配置
    manager.ShowAllPluginConfigurations();
    
    // 清理资源
    Console.WriteLine("\n=== 清理资源 ===");
    manager.CleanupAllPlugins();
}

本章小结

本章详细介绍了 C# 中的接口:

关键要点:

  • 接口定义:只包含成员签名,不包含实现
  • 接口实现:类必须实现接口的所有成员
  • 多接口实现:一个类可以实现多个接口
  • 显式实现:解决接口成员名称冲突
  • 接口继承:接口可以继承其他接口

接口的优势:

  • 契约定义:明确规定类必须实现的功能
  • 多重继承:C# 不支持类的多重继承,但支持多接口实现
  • 松耦合:依赖接口而不是具体实现
  • 多态性:通过接口引用实现多态

设计原则:

  • 接口隔离原则:接口应该小而专一
  • 依赖倒置原则:依赖抽象而不是具体实现
  • 开闭原则:对扩展开放,对修改关闭

最佳实践:

  • 接口名称以 I 开头(如 IDisposable)
  • 保持接口简单和专一
  • 避免在接口中定义过多成员
  • 合理使用接口继承
  • 考虑向后兼容性

接口 vs 抽象类:

  • 接口:纯契约,支持多重实现,无状态
  • 抽象类:可包含实现,单继承,可有状态

应用场景:

  • 插件系统架构
  • 依赖注入框架
  • 策略模式实现
  • 回调机制设计

下一步: 在下一章中,我们将学习泛型,了解如何编写类型安全且可重用的代码。

延伸阅读

本站内容仅供学习和研究使用。