一、接口的核心概念
接口是 C# 中一种完全抽象的类型,它只定义了 "做什么" 的规范(方法、属性、事件、索引器的签名),但不实现 "怎么做"。你可以把它理解为一份 "契约",任何实现这个接口的类都必须遵守这份契约,实现接口中定义的所有成员。
关键特性:
- 接口成员默认是
public的,不能加访问修饰符(private/protected等)。 - 接口不能包含字段、构造函数,也不能有方法体。
- 一个类可以实现多个接口(弥补了 C# 单继承的限制)。
- 接口可以继承其他接口。
二、接口的定义与实现
1. 定义接口
接口命名通常以I开头(行业最佳实践),例如IFlyable、IRunable。
csharp
运行
// 定义一个"可飞行"的接口
public interface IFlyable
{
// 方法签名:无访问修饰符、无方法体
void Fly();
// 属性签名:只定义get/set,无实现
int MaxAltitude { get; set; }
}
// 定义一个"可奔跑"的接口
public interface IRunable
{
void Run();
int Speed { get; } // 只读属性
}
2. 实现接口
类使用:符号实现接口,必须实现接口中所有 成员,且成员必须是public(因为接口成员默认 public)。
csharp
运行
// 鸟类实现IFlyable接口
public class Bird : IFlyable
{
// 实现接口的属性
public int MaxAltitude { get; set; }
// 实现接口的方法
public void Fly()
{
Console.WriteLine($"鸟在{MaxAltitude}米的高度飞行");
}
}
// 飞机同时实现IFlyable和IRunable(多接口实现)
public class Plane : IFlyable, IRunable
{
// 实现IFlyable的属性
public int MaxAltitude { get; set; }
// 实现IFlyable的方法
public void Fly()
{
Console.WriteLine($"飞机在{MaxAltitude}米的高度巡航");
}
// 实现IRunable的只读属性
public int Speed { get; private set; } = 300;
// 实现IRunable的方法
public void Run()
{
Console.WriteLine($"飞机在跑道上以{Speed}km/h的速度滑行");
}
}
3. 调用接口成员
你可以直接通过类实例调用,也可以将类实例赋值给接口变量(面向接口编程):
csharp
运行
class Program
{
static void Main(string[] args)
{
// 直接调用
Bird sparrow = new Bird();
sparrow.MaxAltitude = 50;
sparrow.Fly(); // 输出:鸟在50米的高度飞行
// 面向接口调用
IFlyable boeing = new Plane();
boeing.MaxAltitude = 10000;
boeing.Fly(); // 输出:飞机在10000米的高度巡航
// 多接口转换
IRunable planeRun = (IRunable)boeing;
planeRun.Run(); // 输出:飞机在跑道上以300km/h的速度滑行
}
}
三、接口的典型应用场景
-
统一行为规范 :比如系统中所有 "可打印" 的对象(文档、图片、报表)都实现
IPrintable接口,包含Print()方法,调用方无需关心具体类型,只需调用Print()。 -
解耦代码 :接口作为方法参数,使方法不依赖具体类,只依赖抽象,提高代码扩展性。例如:
csharp
运行
// 方法接收IFlyable接口,而非具体的Bird/Plane public static void StartFly(IFlyable flyable) { flyable.Fly(); } // 可传入任意实现IFlyable的类 StartFly(new Bird()); StartFly(new Plane()); -
模拟多继承 :C# 类只能单继承,但可实现多个接口,例如
class Student : Person, IStudy, IPlay。
四、接口与抽象类的核心区别
| 特性 | 接口 | 抽象类 |
|---|---|---|
| 成员实现 | 无实现(仅签名) | 可包含抽象 / 非抽象成员 |
| 访问修饰符 | 仅 public(默认) | 可定义 public/protected 等 |
| 继承限制 | 类可实现多个接口 | 类只能继承一个抽象类 |
| 字段 / 构造函数 | 无 | 可包含字段、构造函数 |
| 适用场景 | 定义行为契约 | 定义对象的基类(有共享实现) |
总结
- 接口是 "契约":只定义规范(做什么),不实现逻辑(怎么做),实现类必须遵守契约。
- 核心价值:解决 C# 单继承限制,统一行为规范,降低代码耦合度,支持面向接口编程。
- 使用原则:当需要统一多个不相关类的行为时用接口;当需要为相关类提供共享实现时用抽象类。