Administrator
发布于 2025-10-08 / 2 阅读
0
0

C# 8.3 多态

对于C#初学者,理解多态可以从以下几个简单直观的角度入手:

一、用生活中的例子理解多态

1. "说话"的多态性

// 不同的人说"你好"会有不同的表现
中国人说"你好" → "你好"
美国人说"你好" → "Hello"
日本人说"你好" → "こんにちは"
​
// 同一个指令,不同对象产生不同行为

2. "绘图"的多态性

// 说"画一个图形"
画圆形 → 画出⚪
画方形 → 画出◼
画三角 → 画出▲
​
// 同一个"画"的命令,不同图形有不同实现

二、多态的核心思想

简单理解:

"同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果"

三、从继承到多态的演进

阶段1:普通继承(没有多态)

public class 动物
{
    public void 叫()
    {
        Console.WriteLine("动物发出声音");
    }
}
​
public class 狗 : 动物
{
    // 隐藏父类方法(不好!)
    public new void 叫()
    {
        Console.WriteLine("汪汪!");
    }
}
​
public class 猫 : 动物
{
    public new void 叫()
    {
        Console.WriteLine("喵喵!");
    }
}
​
// 使用
狗 小黄 = new 狗();
猫 小花 = new 猫();
小黄.叫();  // 输出:汪汪!
小花.叫();  // 输出:喵喵!

阶段2:使用多态(正确方式)

public class 动物
{
    // virtual关键字:允许子类重写
    public virtual void 叫()
    {
        Console.WriteLine("动物发出声音");
    }
}
​
public class 狗 : 动物
{
    // override关键字:重写父类方法
    public override void 叫()
    {
        Console.WriteLine("汪汪!");
    }
}
​
public class 猫 : 动物
{
    public override void 叫()
    {
        Console.WriteLine("喵喵!");
    }
}
​
// 使用多态的魅力!
动物 我的宠物1 = new 狗();  // 动物引用指向狗对象
动物 我的宠物2 = new 猫();  // 动物引用指向猫对象
​
我的宠物1.叫();  // 输出:汪汪!(调用狗的版本)
我的宠物2.叫();  // 输出:喵喵!(调用猫的版本)

四、多态的两种实现方式

方式1:继承 + 虚方法(最常用)

public class 图形
{
    public virtual void 绘制()
    {
        Console.WriteLine("绘制基本图形");
    }
}
​
public class 圆形 : 图形
{
    public override void 绘制()
    {
        Console.WriteLine("绘制圆形⚪");
    }
}
​
public class 矩形 : 图形
{
    public override void 绘制()
    {
        Console.WriteLine("绘制矩形◼");
    }
}
​
// 使用
图形[] 所有图形 = new 图形[] { new 圆形(), new 矩形() };
​
foreach (图形 图 in 所有图形)
{
    图.绘制();  // 自动调用正确的版本!
}
// 输出:
// 绘制圆形⚪
// 绘制矩形◼

方式2:抽象类和抽象方法

// 抽象类:不能实例化,只能被继承
public abstract class 支付方式
{
    // 抽象方法:没有实现,子类必须重写
    public abstract void 支付(double 金额);
}
​
public class 支付宝 : 支付方式
{
    public override void 支付(double 金额)
    {
        Console.WriteLine($"支付宝支付:{金额}元");
    }
}
​
public class 微信支付 : 支付方式
{
    public override void 支付(double 金额)
    {
        Console.WriteLine($"微信支付:{金额}元");
    }
}
​
// 使用
支付方式 支付工具 = new 支付宝();
支付工具.支付(100);  // 输出:支付宝支付:100元
​
支付工具 = new 微信支付();
支付工具.支付(200);  // 输出:微信支付:200元

五、实际应用场景

场景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 队伍)
{
    角色.攻击();  // 每个角色用自己的方式攻击
}

六、多态的关键字总结

必须记住的关键字:

  • virtual:在父类中声明"这个方法可以被子类重写"

  • override:在子类中声明"我要重写父类的这个方法"

  • abstract:在抽象类中声明"这个方法子类必须实现"

七、多态的好处(对初学者来说)

1. 代码更灵活

// 可以轻松添加新的图形,不需要修改现有代码
public class 三角形 : 图形
{
    public override void 绘制()
    {
        Console.WriteLine("绘制三角形▲");
    }
}

// 现有的循环代码自动支持新图形!

2. 代码更简洁

// 没有多态(繁琐)
if (图形 is 圆形)
    ((圆形)图形).绘制圆形();
else if (图形 is 矩形)
    ((矩形)图形).绘制矩形();
// ... 更多判断

// 使用多态(简洁)
图形.绘制();  // 自动调用正确的方法

3. 易于维护

添加新功能时,只需要创建新类,不需要修改现有代码。

八、初学者实践建议

第一步:识别多态场景

问自己:"这些对象有共同的行为,但具体实现不同吗?"

  • 不同支付方式的"支付"行为

  • 不同文件格式的"保存"行为

  • 不同通知方式的"发送"行为

第二步:设计基类

public abstract class 通知方式
{
    public abstract void 发送(string 消息);
}

第三步:实现具体类

public class 邮件通知 : 通知方式
{
    public override void 发送(string 消息)
    {
        Console.WriteLine($"发送邮件:{消息}");
    }
}
​
public class 短信通知 : 通知方式
{
    public override void 发送(string 消息)
    {
        Console.WriteLine($"发送短信:{消息}");
    }
}

第四步:使用多态

通知方式 通知工具 = new 邮件通知();
通知工具.发送("你好!");  // 发送邮件:你好!
​
通知工具 = new 短信通知();
通知工具.发送("你好!");  // 发送短信:你好!

九、记住这个简单比喻

多态就像"遥控器":

  • 你按"开机"按钮(同一个命令)

  • 电视 → 打开屏幕

  • 空调 → 启动压缩机

  • 音响 → 播放音乐

同一个按钮,不同设备有不同反应!

多态让你的代码更智能、更灵活、更易于扩展!


评论