C Sharp 接口
外观
C#接口[编辑 | 编辑源代码]
介绍[编辑 | 编辑源代码]
在C#中,接口(Interface)是一种引用类型,它定义了一组相关的功能(方法、属性、事件或索引器)的契约,但不提供具体实现。接口允许开发者实现多态行为,并促进代码的解耦和可扩展性。类或结构体可以通过实现接口来承诺提供接口中定义的所有成员。
接口的主要特点包括:
- 不能直接实例化
- 不包含字段(C# 8.0之前)
- 成员默认是公共的且抽象的
- 支持多重继承(一个类可以实现多个接口)
基本语法[编辑 | 编辑源代码]
接口使用interface
关键字定义:
public interface IExampleInterface
{
void DoSomething();
int Calculate(int a, int b);
string Name { get; set; }
}
实现接口的类必须提供所有成员的具体实现:
public class ExampleClass : IExampleInterface
{
public string Name { get; set; }
public void DoSomething()
{
Console.WriteLine("Doing something...");
}
public int Calculate(int a, int b)
{
return a + b;
}
}
接口特性详解[编辑 | 编辑源代码]
显式接口实现[编辑 | 编辑源代码]
当类实现多个含有相同成员名的接口时,可以使用显式实现来消除歧义:
interface IFirst
{
void Method();
}
interface ISecond
{
void Method();
}
class Implementation : IFirst, ISecond
{
void IFirst.Method() => Console.WriteLine("IFirst implementation");
void ISecond.Method() => Console.WriteLine("ISecond implementation");
}
调用方式:
var obj = new Implementation();
((IFirst)obj).Method(); // 输出: IFirst implementation
((ISecond)obj).Method(); // 输出: ISecond implementation
默认接口方法(C# 8.0+)[编辑 | 编辑源代码]
C# 8.0引入了接口方法的默认实现:
public interface ILogger
{
void Log(string message);
// 默认实现
void LogError(string error) => Log($"ERROR: {error}");
}
接口继承[编辑 | 编辑源代码]
接口可以继承其他接口:
public interface IReadable
{
string Read();
}
public interface IWritable : IReadable
{
void Write(string content);
}
类实现IWritable
时必须同时实现IReadable
的成员。
实际应用案例[编辑 | 编辑源代码]
插件系统[编辑 | 编辑源代码]
接口常用于实现插件架构:
public interface IPlugin
{
string Name { get; }
void Execute();
}
public class CalculatorPlugin : IPlugin
{
public string Name => "Calculator Plugin";
public void Execute()
{
Console.WriteLine("Calculator plugin is running...");
// 具体计算逻辑
}
}
依赖注入[编辑 | 编辑源代码]
现代框架如ASP.NET Core广泛使用接口进行依赖注入:
public interface IEmailService
{
void SendEmail(string to, string subject, string body);
}
public class SmtpEmailService : IEmailService
{
public void SendEmail(string to, string subject, string body)
{
// 使用SMTP发送邮件
}
}
// 在控制器中使用
public class UserController
{
private readonly IEmailService _emailService;
public UserController(IEmailService emailService)
{
_emailService = emailService;
}
}
接口 vs 抽象类[编辑 | 编辑源代码]
主要区别:
- 抽象类可以包含实现,接口不能(C# 8.0前)
- 类只能继承一个抽象类,但可以实现多个接口
- 抽象类可以包含字段,接口不能(C# 8.0前)
- 抽象类可以有构造函数,接口不能
最佳实践[编辑 | 编辑源代码]
1. 使用接口定义角色而不是类型
2. 遵循接口隔离原则(ISP) - 保持接口小巧专注
3. 使用I
前缀命名接口(如IEnumerable
)
4. 考虑使用接口进行单元测试的模拟
5. 在需要跨组件边界通信时优先使用接口
高级主题[编辑 | 编辑源代码]
协变和逆变接口[编辑 | 编辑源代码]
C#支持泛型接口中的变体:
// 协变(out)
interface IEnumerable<out T> { /*...*/ }
// 逆变(in)
interface IComparer<in T> { /*...*/ }
数学表示:
- 协变:若,则
- 逆变:若,则
接口重新实现[编辑 | 编辑源代码]
派生类可以重新实现接口:
interface IBase { void Method(); }
class Base : IBase { public void Method() => Console.WriteLine("Base"); }
class Derived : Base, IBase { public new void Method() => Console.WriteLine("Derived"); }
总结[编辑 | 编辑源代码]
C#接口是面向对象设计中的强大工具,它:
- 促进松耦合设计
- 实现多态行为
- 支持多重继承
- 提高代码可测试性
- 是现代框架(如.NET Core)的基础
通过合理使用接口,可以创建更灵活、可维护和可扩展的应用程序架构。