接口是 C# 面向对象体系里的核心组件,和类、抽象类相辅相成,也是实现多态、依赖倒置、模块解耦 的关键。它只定义行为规范,不实现具体逻辑,在框架开发、业务分层、设计模式中使用频率极高。本文结合语法、案例、场景、对比,完整讲解接口的用法与实战要点。
一、什么是接口
接口可以理解为一套行为契约 / 标准 ,仅声明方法、属性、事件、索引器,没有字段,也不包含实现代码。 类或结构体实现接口,就必须遵守这份契约,完成所有成员的具体逻辑。
C# 接口特点:
- 接口默认成员为
public,不能手动添加访问修饰符; - 不能定义构造函数、实例字段;
- 一个类可以同时实现多个接口(弥补 C# 单类继承的短板);
- 接口之间支持继承。
二、基础语法与简单示例
1. 定义接口
语法:interface 接口名,命名建议以大写 I 开头(行业通用规范)。
cs
// 定义行为接口:具备"奔跑"能力
public interface IRun
{
// 声明方法,无实现
void Run();
}
// 定义属性接口
public interface IAnimalInfo
{
string Name { get; set; }
}
2. 类实现接口
使用 : 接口名 实现接口,必须实现接口中所有成员。
cs
// 狗类 实现 IRun、IAnimalInfo 两个接口
public class Dog : IRun, IAnimalInfo
{
// 实现接口属性
public string Name { get; set; }
// 实现接口方法
public void Run()
{
Console.WriteLine($"{Name} 四条腿快速奔跑");
}
}
// 人类 实现两个接口
public class Person : IRun, IAnimalInfo
{
public string Name { get; set; }
public void Run()
{
Console.WriteLine($"{Name} 双脚向前奔跑");
}
}
- 调用使用
cs
class Program
{
static void Main()
{
// 1. 实例化子类调用
Dog dog = new Dog { Name = "旺财" };
dog.Run();
// 2. 接口引用指向实现类(接口多态,核心用法)
IRun runObj = new Person { Name = "小李" };
runObj.Run();
}
}
三、接口多态(核心价值)
和类的多态逻辑一致,接口类型引用指向实现类对象,统一调用入口,不同实现类执行不同逻辑,是项目解耦的核心手段。
实战:接口数组统一管理
cs
IRun[] runners =
{
new Dog { Name = "大黄" },
new Person { Name = "小王" }
};
// 统一遍历调用,无需区分具体类型
foreach (var item in runners)
{
item.Run();
}
优势:新增「猫、兔子」等类,只需实现对应接口,原有遍历代码完全不用修改,符合开闭原则。
四、接口的显式实现与隐式实现
当一个类实现多个接口,且接口存在同名成员时,会出现冲突,此时需要区分两种实现方式。
1. 隐式实现(默认写法)
直接实现接口成员,成员默认公开,类实例、接口引用都能调用,是最常用写法。 上面所有示例均为隐式实现。
2. 显式实现
语法:接口名.成员名,实现后成员变为私有 ,只能通过接口引用调用,类实例无法直接访问。
适用场景:多个接口存在同名方法,需要区分不同接口的逻辑。
cs
public interface IFly
{
void Action();
}
public interface ISwim
{
void Action();
}
// 显式实现两个同名方法
public class Duck : IFly, ISwim
{
void IFly.Action()
{
Console.WriteLine("鸭子展翅飞翔");
}
void ISwim.Action()
{
Console.WriteLine("鸭子水中游泳");
}
}
调用方式:
cs
Duck duck = new Duck();
// duck.Action(); // 报错,无法直接调用
IFly fly = duck;
fly.Action(); // 执行飞翔逻辑
ISwim swim = duck;
swim.Action(); // 执行游泳逻辑
五、接口继承
接口可以继承另一个 / 多个接口,子接口会包含父接口的所有成员。
cs
// 父接口
public interface ILive
{
void Live();
}
// 子接口,继承 ILive
public interface IWildAnimal : ILive
{
void Hunt();
}
// 实现子接口,必须实现父+子所有成员
public class Tiger : IWildAnimal
{
public void Live()
{
Console.WriteLine("老虎生存于野外");
}
public void Hunt()
{
Console.WriteLine("老虎捕猎食物");
}
}
六、C# 8.0+ 接口新特性:默认方法实现
传统接口只能声明成员,C# 8 及以上版本支持接口内编写默认方法实现。 如果实现类不需要改写逻辑,可直接使用接口默认实现。
cs
public interface ISay
{
// 带默认实现的方法
void Say()
{
Console.WriteLine("通用打招呼");
}
}
// 实现类不重写,直接使用默认逻辑
public class Cat : ISay
{
}
七、接口 vs 抽象类(面试高频对比)
很多人混淆接口和抽象类,这里做清晰区分:
表格
| 对比项 | 接口(Interface) | 抽象类(abstract class) |
|---|---|---|
| 成员 | 无字段、无构造函数;可包含方法 / 属性声明 | 可拥有字段、构造函数、普通方法 |
| 继承 | 一个类可实现多个接口 | 一个类只能继承一个抽象类(单继承) |
| 访问修饰符 | 成员默认 public,不能自定义 | 可使用任意访问修饰符 |
| 实现 | C#8 前无实现;新版支持默认实现 | 可包含抽象成员 + 已实现成员 |
| 设计思想 | 定义行为规范(能做什么) | 定义对象共性(是什么) |
使用选择建议
- 想定义一组行为标准、多兼容扩展 → 用接口;
- 多个类存在大量公共字段 / 通用逻辑,抽取公共父类 → 用抽象类;
- 既要统一共性,又要拓展不同行为 → 抽象类 + 接口组合使用。
八、实际开发中的经典使用场景
- 分层架构 仓储层、服务层统一定义接口(
IUserService、IUserRepository),上层依赖接口而非具体类,实现解耦,方便后期替换实现类。 - 依赖注入 .NET Core/ASP.NET Core DI 容器优先注册接口,是框架标配用法。
- 统一功能约束 如
IDisposable(资源释放接口)、IEnumerable(集合遍历接口),.NET 底层大量接口规范组件行为。 - 插件化 / 扩展功能 约定插件统一实现某个接口,主程序无需关心插件具体类型。
九、总结
- 接口是行为契约,只定标准,核心作用是规范、解耦、实现多态;
- 支持多接口实现,弥补单类继承缺陷,是面向对象扩展能力的关键;
- 同名成员冲突时使用显式实现,普通场景优先隐式实现;
- 区分接口与抽象类:接口看行为,抽象类看本质;
- 现代.NET 开发中,接口是分层架构、依赖注入、框架设计的基础,务必熟练掌握。