抽象类是 C# 面向对象编程中用于构建类层次结构的重要工具。它位于“普通类”和“接口”之间,既可以定义行为的标准(抽象方法),也可以提供通用的实现(普通方法)。
抽象类是一种不能被实例化的类,它的主要作用是作为其他类的基类 (Base Class)。
抽象方法是抽象类的核心特征。
* 语法特征:
* 实现规则:
// 格式示例 abstract class Max // 抽象类 { // 抽象方法:只有定义,没有实现 public abstract void Run(); }
以下代码展示了如何定义抽象类,以及如何在子类中实现它,并利用多态性进行调用。
using System; namespace AbstractDemo { class Program { static void Main(string[] args) { // 1. 实例化子类 // 抽象类不能 new,但子类可以 Test test = new Test(); test.Fangfa1(); // 调用子类重写后的方法 // 2. 抽象类的多态性 (核心知识点) // 虽然不能 new Chouxiang_class(),但可以声明该类型的变量 // 父类变量引用子类实例 Chouxiang_class test2 = test; test2.Fangfa1(); // 依然调用的是 Test 类中重写的逻辑 test2.num = 4; // 访问抽象类中定义的公共字段 Console.WriteLine($"Num value: {test2.num}"); } } // ==== 抽象类 (父类) ==== // 定义框架 abstract class Chouxiang_class { // 1. 抽象方法:强制子类必须实现 // 注意:没有方法体 {} public abstract void Fangfa1(); // 2. 普通字段:子类直接继承使用 public int num; // 3. 普通方法:抽象类也可以包含已实现的方法 public void CommonMethod() { Console.WriteLine("这是抽象类里的通用方法,子类可以直接用。"); } } // ==== 子类 ==== // 继承抽象类 class Test : Chouxiang_class { // 必须使用 override 关键字重写父类的抽象方法 public override void Fangfa1() { Console.WriteLine("子类 Test 已具体实现 Fangfa1 的逻辑"); } } }
很多初学者会问:“为什么不直接写个普通父类,或者直接写个子类,非要搞个抽象类?”
如果你用普通父类定义一个空方法让子类去重写,子类可能会忘记重写。但使用 ``abstract``,编译器会强制子类必须重写,否则代码无法编译通过。这保证了所有子类都具备特定的行为。
抽象类不仅仅只有抽象方法,它还可以包含普通方法和字段(如上面的 ``num`` 字段)。这允许把所有子类共有的逻辑(比如日志记录、ID属性)放在父类中,避免重复代码。
如案例中的 ``Chouxiang_class test2 = test;``。我们可以用一个抽象的父类类型来管理一群不同的子类对象,这在工厂模式和插件开发中非常有用。
* 错误 1: 试图实例化抽象类。
* 错误 2: 抽象方法写了方法体。
* 错误 3: 子类没有重写抽象方法。
* 错误 4: 忘记写 ``override``。