Administrator
发布于 2025-10-14 / 0 阅读
0
0

抽象类是什么

多态的核心是:

同一个接口(方法名),不同对象有不同实现。

抽象类实现多态,就是 C# 提供的一种“强制子类实现”多态的机制。 我们一步步来理解 👇


🧩 一、什么是抽象类(abstract class)

在 C# 中:

  • 抽象类(abstract class) 是不能被实例化的类。

  • 它是为了被继承而存在的。

  • 它里面可以包含:

    • 抽象方法(abstract method) → 没有方法体,必须由子类实现;

    • 普通方法 → 可以直接使用;

    • 属性、字段、构造函数 等。


🧠 二、为什么抽象类能实现多态?

因为“抽象方法”规定了一个统一的接口, 不同子类必须提供自己的具体实现

于是我们就可以在运行时, 通过父类引用调用不同子类的实现 —— 这就是 运行时多态


💻 三、简单示例:抽象类实现多态

using System;
​
abstract class Animal
{
    // 抽象方法:没有方法体,子类必须重写
    public abstract void Speak();
}
​
class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("狗在汪汪叫。");
    }
}
​
class Cat : Animal
{
    public override void Speak()
    {
        Console.WriteLine("猫在喵喵叫。");
    }
}
​
class Program
{
    static void Main()
    {
        Animal a1 = new Dog();
        Animal a2 = new Cat();
​
        a1.Speak();  // 输出:狗在汪汪叫。
        a2.Speak();  // 输出:猫在喵喵叫。
    }
}

🔍 运行分析:

  1. Animal 定义了一个“统一的接口” Speak()

  2. DogCat 必须实现它;

  3. 运行时,根据 a1a2 的真实类型(Dog / Cat),执行各自的方法;

  4. 结果就是:同一方法,不同表现 → 多态。


🧩 四、与 virtual 的区别

比较点

virtual 虚方法

abstract 抽象方法

是否有方法体

✅ 有默认实现

❌ 没有方法体

是否必须重写

❌ 可选

✅ 必须重写

是否可实例化

父类可以实例化

父类不能实例化

使用场景

父类提供默认行为

父类只定义接口规范

✅ 简单记忆:

virtual:父类有默认实现,子类可重写。 abstract:父类不给实现,子类必须重写


🧱 五、抽象类多态的典型应用场景

场景

示例

UI组件体系

ShapeCircleRectangle

动物行为模拟

AnimalDogCat

数据访问层

RepositorySqlRepositoryMongoRepository

游戏角色系统

CharacterWarriorMage

这些都有一个共同点: 父类定义“应该做什么”,子类定义“具体怎么做”。


✅ 六、总结一句话

抽象类实现多态: 通过在抽象类中定义抽象方法,让不同子类必须实现该方法, 从而在运行时通过父类引用调用不同子类的实现。

💬 换句话说:

抽象类规定“所有子类都必须会说话”, 但“怎么说”由每个子类自己决定。😄


是否希望我帮你画一张「抽象类实现多态」的结构图? (显示 Animal → Dog/Cat 的继承关系和方法调用方向,非常适合教学或视频讲解用。)

八、练习题

练习1:计算器程序

public abstract class 运算
{
    public abstract double 计算(double a, double b);
}
​
public class 加法 : 运算
{
    public override double 计算(double a, double b)
    {
        return a + b;
    }
}
​
public class 乘法 : 运算
{
    public override double 计算(double a, double b)
    {
        return a * b;
    }
}
​
// 使用多态的计算器
运算 当前运算 = new 加法();
double 结果 = 当前运算.计算(5, 3);  // 8
​
当前运算 = new 乘法();
结果 = 当前运算.计算(5, 3);        // 15

练习2:游戏角色系统

public abstract class 游戏角色
{
    public string 名字;
    public abstract void 攻击();
}
​
public class 战士 : 游戏角色
{
    public override void 攻击()
    {
        Console.WriteLine($"{名字}用剑砍击!");
    }
}
​
public class 法师 : 游戏角色
{
    public override void 攻击()
    {
        Console.WriteLine($"{名字}发射火球!");
    }
}
​
public class 弓箭手 : 游戏角色
{
    public override void 攻击()
    {
        Console.WriteLine($"{名字}射出弓箭!");
    }
}
​
// 在游戏中使用
游戏角色[] 队伍 = new 游戏角色[] 
{
    new 战士() { 名字 = "勇者" },
    new 法师() { 名字 = "魔法师" },
    new 弓箭手() { 名字 = "神射手" }
};
​
foreach (游戏角色 角色 in 队伍)
{
    角色.攻击();  // 每个角色用自己的方式攻击
}

##


评论