C#接口默认实现是C# 8.0版本新增的语言特性,它打破了传统接口只能定义方法签名、不能包含方法实现的限制,允许在接口中直接为方法编写默认的执行逻辑。当某个类实现该接口时,如果没有重写这个带有默认实现的方法,就会自动继承接口中提供的默认逻辑,不需要强制实现该方法。

C#接口默认实现的基本语法
在接口中定义默认方法时,只需要在方法签名后面添加方法体即可,语法和类中定义方法类似,但是接口中的方法默认是公开的,不需要额外添加访问修饰符。下面是一个最基础的接口默认实现示例:
// 定义包含默认方法实现的接口
public interface ILogger
{
// 普通接口方法,没有默认实现,实现类必须重写
void LogError(string message);
// 带有默认实现的接口方法
void LogInfo(string message)
{
Console.WriteLine($"[Info] {DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}");
}
}
// 实现接口的类
public class FileLogger : ILogger
{
// 必须实现没有默认实现的LogError方法
public void LogError(string message)
{
File.AppendAllText("error.log", $"[Error] {DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}n");
}
// 可以选择不重写LogInfo方法,直接使用接口提供的默认实现
}
// 使用示例
class Program
{
static void Main()
{
ILogger logger = new FileLogger();
logger.LogInfo("这是一条信息日志"); // 调用接口的默认实现
logger.LogError("这是一条错误日志"); // 调用FileLogger重写的实现
}
}
接口默认实现的使用场景
接口默认实现最常用的场景是接口升级。假设我们有一个已经广泛使用的接口,现在需要新增一个方法,如果按照传统接口的规则,所有实现了这个接口的类都需要新增该方法的实现,否则会编译报错,这会导致大量的代码修改工作。使用默认实现就可以避免这个问题,新增的方法提供默认逻辑后,已存在的实现类不需要做任何修改就能正常编译运行。
比如我们有一个基础的支付接口,最初只有支付方法:
public interface IPayment
{
bool Pay(decimal amount);
}
现在需要新增一个退款方法,我们可以这样修改接口:
public interface IPayment
{
bool Pay(decimal amount);
// 新增的退款方法,提供默认实现,返回不支持退款的提示
bool Refund(decimal amount)
{
Console.WriteLine("当前支付方式不支持退款");
return false;
}
}
所有已经实现了IPayment接口的类都不需要修改,只有在需要支持退款的类中重写Refund方法即可。
使用接口默认实现的注意事项
- 接口中的默认方法只能是实例方法,不能包含静态字段、实例字段,也不能定义静态构造函数,但是可以包含静态方法。
- 实现类如果想要调用接口中的默认方法,需要通过接口类型的变量来调用,不能直接通过实现类的实例调用,因为默认方法不会成为实现类的成员。
- 如果实现类继承了多个接口,且这些接口包含相同签名且有默认实现的方法,那么实现类必须重写这个方法,否则会编译报错。
- 接口默认实现中不能调用接口中没有定义的其他抽象方法,因为接口无法保证实现类一定会实现那些方法。
下面是一个展示多接口相同默认方法冲突的示例:
public interface IAnimal
{
void Eat()
{
Console.WriteLine("动物吃东西");
}
}
public interface IBird
{
void Eat()
{
Console.WriteLine("鸟吃虫子");
}
}
// 实现类必须重写Eat方法,解决冲突
public class Sparrow : IAnimal, IBird
{
public void Eat()
{
Console.WriteLine("麻雀吃谷物和虫子");
}
}
接口默认实现与抽象类的区别
很多开发者会混淆接口默认实现和抽象类的作用,两者的核心区别如下:
| 对比项 | 接口默认实现 | 抽象类 |
|---|---|---|
| 继承限制 | 类可以实现多个带默认实现的接口 | 类只能继承一个抽象类 |
| 字段支持 | 不能包含实例字段、静态字段 | 可以包含各种字段 |
| 构造函数 | 不能有实例构造函数、静态构造函数 | 可以有构造函数 |
| 访问修饰符 | 接口成员默认是public,不能修改 | 可以定义不同访问修饰符的成员 |
因此接口默认实现并不能替代抽象类,它更适合用于扩展已有接口的功能,而抽象类更适合封装一组相关类的通用逻辑和状态。
C#接口默认实现接口默认方法default_interface_implementation修改时间:2026-06-15 15:18:25