C#里面的Abstract和Virtual
在C#中,abstract(抽象)和virtual(虚拟)都是用于实现多态性的关键字,但它们的用法和特性有显著区别:
1. virtual 关键字
- 用途:用于修饰方法、属性、索引器或事件,允许在派生类中通过
override关键字重写 - 特点:
- 必须有默认实现(方法体)
- 派生类可以选择重写或不重写
- 只能在非抽象类中使用
public class Animal
{
// 虚拟方法,有默认实现
public virtual void MakeSound()
{
Console.WriteLine("动物发出声音");
}
}
public class Dog : Animal
{
// 重写基类的虚拟方法
public override void MakeSound()
{
Console.WriteLine("狗汪汪叫");
}
}
2. abstract 关键字
- 用途:用于修饰类、方法、属性、索引器或事件,定义必须由派生类实现的成员
- 特点:
- 抽象方法没有实现(没有方法体),以分号结束
- 包含抽象成员的类必须声明为抽象类
- 派生类必须实现所有抽象成员(除非派生类也是抽象类)
- 抽象类不能被实例化
// 抽象类
public abstract class Shape
{
// 抽象方法,没有实现
public abstract double CalculateArea();
}
public class Circle : Shape
{
public double Radius { get; set; }
// 必须实现基类的抽象方法
public override double CalculateArea()
{
return Math.PI * Radius * Radius;
}
}
主要区别对比
| 特性 | virtual |
abstract |
|---|---|---|
| 实现 | 必须有实现 | 没有实现 |
| 所在类 | 非抽象类 | 必须在抽象类中 |
| 派生类要求 | 可选择重写 | 必须重写(除非派生类也是抽象类) |
| 适用场景 | 提供默认行为,允许修改 | 只定义接口,不提供实现 |
使用建议
- 当你希望提供一个默认实现,同时允许派生类修改时,使用
virtual - 当你希望强制派生类提供自己的实现,而不提供默认行为时,使用
abstract - 抽象类通常作为其他类的基类,定义共同的接口但不提供完整实现