Skip to Content
MUZINET-NOTE 4.0 is released 🎉
技术知识库C#抽象类-abstract

🧩 C# 抽象类详解

抽象类(abstract class)是 面向对象编程(OOP) 中的重要概念,
用于定义一个 不能直接实例化 的类,
作为其他类的「蓝图」存在。它通常用来表示一类对象的共同特征与行为约束。


🧱 一、定义与基本语法

public abstract class Animal { // 抽象方法(没有实现)——必须由子类实现 public abstract void Speak(); // 虚方法(可以被子类重写,也可以直接使用) public virtual void Move() { Console.WriteLine("Animal is moving..."); } // 普通方法(有固定实现,子类不能重写) public void Eat() { Console.WriteLine("Animal is eating..."); } }
  • abstract 关键字修饰类或方法。

  • 抽象类 不能被实例化

  • 抽象类中可以包含:

    • 抽象方法(必须由子类实现)
    • 普通方法(可直接继承使用)
    • 属性、字段、构造函数等。

🐕 二、继承与实现

public class Dog : Animal { // 实现抽象方法 public override void Speak() { Console.WriteLine("Woof!"); } // 重写虚方法 public override void Move() { Console.WriteLine("Dog is running..."); } }

使用:

Animal animal = new Dog(); animal.Speak(); // 输出:Woof! animal.Move(); // 输出:Dog is running... animal.Eat(); // 输出:Animal is eating...

✅ 说明:

  • 通过 向上转型(Upcasting),可以用 Animal 类型引用具体子类对象。
  • 实现了多态行为:相同的方法,不同的实现。
方法类型关键字是否有实现是否必须重写是否可选重写示例
抽象方法abstract❌ 否✅ 必须❌ 不可选public abstract void Speak();
虚方法virtual✅ 有默认实现❌ 不强制✅ 可选public virtual void Move() { }
普通方法✅ 有实现❌ 不允许❌ 不允许public void Eat() { }

⚖️ 三、抽象类 vs 接口(interface)

对比项抽象类接口
是否能包含字段✅ 可以❌ 不可以
是否能包含实现✅ 可以(普通方法)✅ 从 C# 8 起可以有默认实现
是否支持多继承❌ 不支持✅ 支持多接口实现
构造函数✅ 可以❌ 不可以
用途表示类之间的继承关系表示行为契约

💬 一般来说,当多个类有相似逻辑时,用抽象类; 当只需定义“规范”时,用接口。


🧠 四、常见面试题

❓ 1. 抽象类可以包含构造函数吗?

✅ 可以。用于初始化共有字段。 但仍不能直接通过 new 实例化该类。

public abstract class Shape { protected Shape(string name) { Name = name; } public string Name { get; } }

❓ 2. 抽象类能被 sealed 修饰吗?

❌ 不行。 sealed 表示类不能被继承,而抽象类的意义正是被继承。


❓ 3. 抽象方法可以是 static 吗?

❌ 不可以。 静态方法不能被重写,而抽象方法必须由子类重写。


❓ 4. 抽象类能实现接口吗?

✅ 可以,且子类会继承接口约定。

public interface IMovable { void Move(); } public abstract class Vehicle : IMovable { public abstract void Move(); }

🧩 五、实践示例:

模板方法模式(Template Method)

抽象类常用于「模板方法模式」:

public abstract class DataProcessor { public void Process() { Load(); Transform(); Save(); } protected abstract void Load(); protected abstract void Transform(); protected abstract void Save(); } public class CsvProcessor : DataProcessor { protected override void Load() => Console.WriteLine("Loading CSV..."); protected override void Transform() => Console.WriteLine("Transforming CSV data..."); protected override void Save() => Console.WriteLine("Saving results..."); }

使用:

DataProcessor processor = new CsvProcessor(); processor.Process();

👉 输出:

Loading CSV... Transforming CSV data... Saving results...

这是一种典型的 OOP 设计模式: 父类定义流程,子类定义细节。

EF实体继承设计模式

✅ 一、典型示例

public abstract class BaseEntity { public int Id { get; set; } public DateTime CreatedTime { get; set; } = DateTime.UtcNow; public DateTime? UpdatedTime { get; set; } public bool IsDeleted { get; set; } = false; }

然后其他实体继承这个抽象类:

public class User : BaseEntity { public string Name { get; set; } = default!; public string Email { get; set; } = default!; }

这样所有表都会自动带上这些公共字段。 EF 会在迁移时自动识别并生成这些列。


⚠️ 六、注意事项

  • 抽象类中至少要有一个抽象成员,否则通常可改为普通类。
  • 抽象方法 不能有实现体
  • 子类必须使用 override 实现抽象方法。
  • 如果子类没有实现所有抽象方法,它也必须声明为 abstract

🔍 七、小结

特性说明
关键字abstract
作用定义模板类,约束子类实现
能否实例化❌ 不可
是否可继承✅ 必须被继承
是否可包含实现✅ 可以
常见应用模板方法模式、基类设计、框架扩展点

🧭 推荐阅读


💬 “抽象类的核心不是省代码,而是设计思维: 把变化的部分留给子类,让稳定的部分在父类中复用。”