C# 抽象类与接口的区别详解
在 C# 中,抽象类(Abstract Class) 和 接口(Interface) 都用于实现面向对象编程中的抽象和多态,但它们的设计目的和使用场景有显著差异。
1. 定义与核心目的
抽象类
表示一种 "是什么"(Is-A) 关系,用于定义一组相关类的 基类。
可以包含 具体方法(有实现) 和 抽象方法(无实现)。
强调代码复用,提供部分通用实现,子类通过继承扩展或重写。
接口
表示一种 "能做什么"(Can-Do) 关系,定义一组 行为契约。
仅包含方法、属性、事件或索引器的 签名(无具体实现,C# 8.0+ 允许默认实现)。
强调多态性,用于解耦实现和定义
2. 成员类型
3. 继承与实现
抽象类
一个类 只能继承一个抽象类(C# 不支持多类继承)。
子类必须实现所有抽象方法(除非子类本身也是抽象类)。
接口
一个类 可以实现多个接口。
实现接口的类必须提供所有成员的实现(除非使用默认实现)。
接口可以继承其他接口(允许多继承)。
4. 设计场景
使用抽象类
当多个类有 共享的代码逻辑 时(复用基类代码)。
需要定义 非公共成员(如 protected 方法)。
需要为子类提供 默认实现 或 强制约束。
public abstract class Animal {
protected int Age; // 字段
public abstract void MakeSound(); // 抽象方法
public void Sleep() { // 具体方法
Console.WriteLine("Sleeping...");
}
}使用接口
当多个 不相关类需要相同行为 时(如 IDisposable)。
需要定义 跨不同继承树的类的共同契约。
实现轻量级多态(避免继承层次过深)。
public interface IFlyable {
void Fly(); // 默认无实现(C# 8.0+ 允许默认实现)
}
public class Bird : Animal, IFlyable {
public void Fly() => Console.WriteLine("Flying with wings");
}
public class Drone : IFlyable {
public void Fly() => Console.WriteLine("Flying with propellers");
}5. 版本控制
抽象类
添加新方法时,可以设为 virtual 并提供默认实现,不影响现有子类。
修改基类可能影响所有子类。
接口
添加新成员会破坏所有实现该接口的类(C# 8.0+ 的默认实现可缓解此问题)。
更适合稳定、无需频繁变更的契约。
6. 多态性
抽象类:通过继承实现多态,强调 纵向扩展(父子类层次)。
接 口: 通过实现多个接口实现多态,强调 横向扩展(不同类共享行为)。
实际开发中:
优先用 接口 定义行为契约(如 IEnumerable, IDisposable)
用 抽象类 封装共享逻辑(如 Stream、ControllerBase)
两者可以结合使用(如抽象类实现接口,提供部分通用逻辑)