在 c# 中,抽象类(abstract class) 和接口(interface) 都是实现多态性的重要机制,用于定义规范并约束子类 / 实现类的行为,但它们在设计目的和使用场景上有显著区别。
一、相同点
无法实例化 两者都不能直接创建对象,只能作为父类(抽象类)或契约(接口)被继承 / 实现。
// 错误:无法实例化抽象类 abstractclass ac = new abstractclass(); // 错误:无法实例化接口 iinterface itf = new iinterface();
包含未实现的成员 都可以定义需要子类 / 实现类具体实现的方法(抽象方法 / 接口方法)。
支持多态 子类 / 实现类的对象可以赋值给抽象类 / 接口类型的变量,调用时会执行具体实现。
// 多态示例 abstractclass obj1 = new concreteclass(); // 抽象类多态 iinterface obj2 = new interfaceimpl(); // 接口多态 obj1.abstractmethod(); // 执行子类实现 obj2.interfacemethod(); // 执行实现类方法
二、不同点
| 特性 | 抽象类(abstract class) | 接口(interface) |
|---|---|---|
| 关键字 | abstract class | interface |
| 继承方式 | 单继承(一个类只能继承一个抽象类) | 多实现(一个类可以实现多个接口) |
| 成员类型 | 可包含抽象成员(无实现)和具体成员(有实现) | 只能包含抽象成员(默认无实现,c# 8.0+ 可加默认实现) |
| 访问修饰符 | 成员可以有 public、protected、internal 等修饰符 | 成员默认 public,不能显式添加其他修饰符 |
| 字段 / 属性 | 可以定义字段、普通属性 | 不能定义字段,只能定义属性(自动属性,无字段实现) |
| 构造函数 | 可以有构造函数(供子类调用) | 不能有构造函数 |
| 方法实现 | 可以包含有实现的方法(非抽象方法) | c# 8.0 前:所有方法无实现;c# 8.0+:可添加默认实现 |
| 设计目的 | 表示 "is-a" 关系(继承层次,共享代码) | 表示 "can-do" 关系(功能契约,规范行为) |
三、代码示例
1. 抽象类示例
// 抽象类:包含抽象方法和具体方法
public abstract class shape
{
// 字段(抽象类可定义字段)
protected string _color;
// 构造函数(抽象类可有构造函数)
public shape(string color)
{
_color = color;
}
// 抽象方法(必须由子类实现)
public abstract double getarea();
// 具体方法(提供默认实现,子类可重写)
public virtual void printcolor()
{
console.writeline($"颜色:{_color}");
}
}
// 继承抽象类(单继承)
public class circle : shape
{
private double _radius;
public circle(string color, double radius) : base(color)
{
_radius = radius;
}
// 实现抽象方法
public override double getarea()
{
return math.pi * _radius * _radius;
}
}2. 接口示例
// 接口:定义行为规范
public interface imovable
{
// 接口方法(默认public,无实现)
void move();
// c# 8.0+ 可添加默认实现
void stop()
{
console.writeline("停止移动");
}
}
// 实现接口(可多实现)
public class car : imovable
{
// 必须实现接口的抽象方法
public void move()
{
console.writeline("汽车行驶中...");
}
// 可选:重写接口的默认实现
public void stop()
{
console.writeline("汽车刹车停止");
}
}四、使用场景选择
优先使用抽象类:
- 需要在多个相关类间共享代码(字段、方法实现)。
- 定义的是 "is-a" 关系(如
shape与circle、rectangle)。 - 需要控制成员的访问权限(如
protected方法供子类调用)。
优先使用接口:
- 定义不相关类的共同行为(如
imovable可被car、bird实现)。 - 需要多继承能力(一个类实现多个接口)。
- 仅需规范行为,不涉及代码共享(如框架中的回调接口)。
总结
- 抽象类是 "部分实现" 的基类,强调继承和代码复用,适合构建类的层次结构。
- 接口是 "纯规范" 的契约,强调行为一致性,适合跨类别的功能定义。
- 在实际开发中,两者常结合使用(如抽象类实现接口,既提供基础实现又遵循规范)。
到此这篇关于c#抽象类和接口的区别小结的文章就介绍到这了,更多相关c#抽象类和接口区别内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论