当前位置: 首页 > news >正文

C#多态性入门:从零到游戏开发实战

Langchain系列文章目录

01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
07-【深度解析】从GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘

PyTorch系列文章目录

Python系列文章目录

C#系列文章目录

01-C#与游戏开发的初次见面:从零开始的Unity之旅
02-C#入门:从变量与数据类型开始你的游戏开发之旅
03-C#运算符与表达式:从入门到游戏伤害计算实践
04-从零开始学C#:用if-else和switch打造智能游戏逻辑
05-掌握C#循环:for、while、break与continue详解及游戏案例
06-玩转C#函数:参数、返回值与游戏中的攻击逻辑封装
07-Unity游戏开发入门:用C#控制游戏对象移动
08-C#面向对象编程基础:类的定义、属性与字段详解
09-C#封装与访问修饰符:保护数据安全的利器
10-如何用C#继承提升游戏开发效率?Enemy与Boss案例解析
11-C#多态性入门:从零到游戏开发实战


文章目录

  • Langchain系列文章目录
  • PyTorch系列文章目录
  • Python系列文章目录
  • C#系列文章目录
  • 前言
  • 一、什么是多态性
    • 1.1 多态性的定义
    • 1.2 多态性的优势
  • 二、方法重写(override)
    • 2.1 什么是方法重写
    • 2.2 如何在C#中进行方法重写
    • 2.3 方法重写的应用场景
  • 三、虚方法(virtual)
    • 3.1 什么是虚方法
    • 3.2 如何在C#中声明虚方法
    • 3.3 虚方法与抽象方法的区别
  • 四、游戏应用:不同敌人的攻击方式
    • 4.1 设计敌人类层次结构
    • 4.2 在游戏中调用攻击方法
    • 4.3 可视化敌人类结构
  • 五、常见问题及解决方案
    • 5.1 忘记使用override关键字
    • 5.2 误用非虚方法
    • 5.3 多态性的性能影响
  • 六、总结

前言

在游戏开发中,我们常常需要让对象展现出不同的行为。比如,在一个2D射击游戏中,不同类型的敌人可能有各自独特的攻击方式:近战敌人挥剑砍杀,远程敌人发射箭矢,魔法敌人释放魔法球。如果为每种敌人单独写一套攻击代码,工作量会很大,而且代码难以维护。这时,C#的多态性就派上用场了。

多态性是面向对象编程的核心特性之一,它允许对象根据自己的类型灵活地响应相同的方法调用。在C#中,多态性通过**方法重写(override)虚方法(virtual)**来实现。本文将从基础知识入手,逐步深入,带你理解多态性的原理,并在游戏开发中通过一个实际案例展示它的应用。无论你是C#初学者还是想提升游戏编程技能的开发者,这篇文章都能帮到你!


一、什么是多态性

多态性(Polymorphism)是面向对象编程的三大支柱之一(另外两个是封装和继承)。它让不同类的对象可以用各自的方式响应同一个方法调用,从而让代码更灵活、更易扩展。

1.1 多态性的定义

简单来说,多态性就是“一个接口,多种实现”。在C#中,它允许子类重写父类的方法,从而在调用时执行子类的特定逻辑。

举个生活中的例子:假设你有一只宠物,它会发出声音。你可以说“叫一声”,但具体是“汪汪”还是“喵喵”,取决于它是狗还是猫。这种灵活性就是多态性的体现。

在代码中,多态性通常通过继承和方法重写实现。让我们看一个简单的例子:

public class Animal
{
    public virtual void MakeSound() // 虚方法,允许子类重写
    {
        Console.WriteLine("动物发出声音");
    }
}

public class Dog : Animal
{
    public override void MakeSound() // 重写父类方法
    {
        Console.WriteLine("汪汪");
    }
}

public class Cat : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("喵喵");
    }
}

运行代码:

Animal dog = new Dog();
dog.MakeSound(); // 输出: 汪汪

Animal cat = new Cat();
cat.MakeSound(); // 输出: 喵喵

这里,即使dogcat被声明为Animal类型,调用MakeSound()时,仍然会执行它们各自的重写方法。这就是多态性的魅力。

1.2 多态性的优势

多态性为什么重要?它带来了以下好处:

  • 灵活性:同一个方法调用可以有不同的行为。
  • 可扩展性:新增子类时无需修改现有代码。
  • 代码复用:通过继承和重写,减少重复代码。
  • 易维护:逻辑清晰,方便管理和调试。

在游戏开发中,多态性特别有用。比如,我们可以用它来统一管理敌人的攻击行为,而无需为每种敌人写独立的逻辑。


二、方法重写(override)

方法重写是实现多态性的核心机制。它允许子类重新定义父类的方法,提供自己的实现。

2.1 什么是方法重写

方法重写(Method Overriding)是指子类对父类中已有的方法进行“覆盖”,让子类对象调用该方法时执行自己的逻辑。

需要注意的是,方法重写和**方法重载(Overloading)**不同:

  • 重写:发生在继承关系中,方法名和参数列表相同。
  • 重载:在同一类中,方法名相同但参数列表不同。

2.2 如何在C#中进行方法重写

在C#中,方法重写有几个关键点:

  1. 父类方法必须标记为virtual(虚方法)或abstract(抽象方法)。
  2. 子类使用override关键字重写方法。

来看一个代码示例:

public class Enemy
{
    public virtual void Attack() // 声明虚方法
    {
        Console.WriteLine("敌人进行攻击");
    }
}

public class MeleeEnemy : Enemy
{
    public override void Attack() // 重写方法
    {
        Console.WriteLine("近战敌人挥剑攻击");
    }
}

运行代码:

Enemy enemy = new MeleeEnemy();
enemy.Attack(); // 输出: 近战敌人挥剑攻击

这里,Attack()方法被标记为virtual,子类MeleeEnemyoverride重写了它。即使enemyEnemy类型,调用时仍执行子类的实现。

2.3 方法重写的应用场景

方法重写在游戏开发中有很多实际用途:

  • 敌人行为:不同敌人重写攻击方法。
  • 角色技能:不同职业的玩家重写技能逻辑。
  • UI绘制:自定义UI元素的显示方式。

通过重写,我们可以让代码更模块化,避免重复逻辑。


三、虚方法(virtual)

虚方法是多态性的基础,它允许子类对方法进行重写。

3.1 什么是虚方法

虚方法是用virtual关键字声明的方法。它有一个默认实现,但子类可以选择重写它。相比之下,非虚方法不能被重写,调用时总是执行父类的实现。

3.2 如何在C#中声明虚方法

声明虚方法很简单,只需在方法前加上virtual关键字:

public class Player
{
    public virtual void UseSkill()
    {
        Console.WriteLine("玩家使用默认技能");
    }
}

public class Warrior : Player
{
    public override void UseSkill()
    {
        Console.WriteLine("战士挥砍大剑");
    }
}

运行代码:

Player player = new Warrior();
player.UseSkill(); // 输出: 战士挥砍大剑

3.3 虚方法与抽象方法的区别

虚方法和抽象方法都可以被重写,但有以下不同:

  • 虚方法:有默认实现,子类可选是否重写。
  • 抽象方法:无实现,子类必须重写,且只能在抽象类中使用。

示例:

public abstract class Animal
{
    public abstract void MakeSound(); // 抽象方法
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("汪汪");
    }
}

选择建议:

  • 如果父类有通用实现,用虚方法。
  • 如果需要强制子类实现,用抽象方法。

四、游戏应用:不同敌人的攻击方式

让我们通过一个游戏开发案例,实践多态性的应用。假设我们要设计一个2D射击游戏,包含多种敌人,每种敌人有独特的攻击方式。

4.1 设计敌人类层次结构

首先,定义一个基类Enemy,包含通用属性和一个虚方法Attack()

public class Enemy
{
    public string Name { get; set; }
    public int Health { get; set; }

    public Enemy(string name, int health)
    {
        Name = name;
        Health = health;
    }

    public virtual void Attack()
    {
        Console.WriteLine($"{Name} 进行攻击");
    }
}

然后,创建几个派生类:

public class MeleeEnemy : Enemy
{
    public MeleeEnemy(string name, int health) : base(name, health) { }

    public override void Attack()
    {
        Console.WriteLine($"{Name} 挥舞利剑,造成近战伤害!");
    }
}

public class RangedEnemy : Enemy
{
    public RangedEnemy(string name, int health) : base(name, health) { }

    public override void Attack()
    {
        Console.WriteLine($"{Name} 射出箭矢,远程打击敌人!");
    }
}

public class MagicEnemy : Enemy
{
    public MagicEnemy(string name, int health) : base(name, health) { }

    public override void Attack()
    {
        Console.WriteLine($"{Name} 释放魔法球,引发魔法爆炸!");
    }
}

4.2 在游戏中调用攻击方法

在游戏中,我们可以用一个列表管理所有敌人,并统一调用它们的Attack()方法:

List<Enemy> enemies = new List<Enemy>
{
    new MeleeEnemy("剑士", 100),
    new RangedEnemy("弓手", 80),
    new MagicEnemy("法师", 60)
};

foreach (var enemy in enemies)
{
    enemy.Attack();
}

输出结果:

剑士 挥舞利剑,造成近战伤害!
弓手 射出箭矢,远程打击敌人!
法师 释放魔法球,引发魔法爆炸!

多态性让代码简洁又灵活。添加新敌人类型时,只需创建新类并重写Attack()方法,无需改动主逻辑。

4.3 可视化敌人类结构

为了更直观地理解,我们可以绘制类图:

Enemy
+string Name
+int Health
+Attack() : virtual
MeleeEnemy
+Attack() : override
RangedEnemy
+Attack() : override
MagicEnemy
+Attack() : override

这个图展示了Enemy基类和三个派生类的继承关系。


五、常见问题及解决方案

在学习和使用多态性时,可能会遇到一些坑。以下是常见问题及解决办法。

5.1 忘记使用override关键字

如果子类方法没有用override,它不会重写父类方法,而是被视为新方法。

错误示例:

public class Enemy
{
    public virtual void Attack()
    {
        Console.WriteLine("敌人攻击");
    }
}

public class MeleeEnemy : Enemy
{
    public void Attack() // 缺少override
    {
        Console.WriteLine("近战攻击");
    }
}

运行:

Enemy enemy = new MeleeEnemy();
enemy.Attack(); // 输出: 敌人攻击

解决办法:确保在子类中使用override

public override void Attack()
{
    Console.WriteLine("近战攻击");
}

5.2 误用非虚方法

非虚方法不能被重写。如果尝试“重写”非虚方法,会隐藏父类方法,而不是实现多态性。

错误示例:

public class Enemy
{
    public void Attack() // 无virtual
    {
        Console.WriteLine("敌人攻击");
    }
}

public class MeleeEnemy : Enemy
{
    public new void Attack() // 使用new隐藏
    {
        Console.WriteLine("近战攻击");
    }
}

运行:

Enemy enemy = new MeleeEnemy();
enemy.Attack(); // 输出: 敌人攻击

解决办法:在父类中将方法标记为virtual

5.3 多态性的性能影响

虚方法调用会通过虚表(vtable)解析,相比直接调用略有开销。但在现代硬件上,这种影响微乎其微,除非是极端高性能需求场景。

优化建议

  • 不需要多态时用非虚方法。
  • 使用sealed关键字密封类,避免虚表开销。

六、总结

通过本文,你应该对C#多态性有了全面的认识。以下是主要内容的总结:

  • 多态性:让对象灵活变化的核心特性,通过方法重写和虚方法实现。
  • 方法重写(override):子类重新定义父类方法,需配合override关键字。
  • 虚方法(virtual):允许子类重写的父类方法,用virtual声明。
  • 游戏应用:通过多态性实现不同敌人的攻击方式,提升代码灵活性和可扩展性。

多态性是游戏开发中的强大工具。建议你在自己的项目中实践,比如为敌人或角色设计不同的行为。动手试试吧,代码是最好的老师!


相关文章:

  • Unity URP自定义Shader支持RenderLayer
  • 【Unity3D实现UI轮播效果】
  • 无人机+evtol:低空经济市场硬通货技术详解
  • HCIP(二)
  • 六十天Linux从0到项目搭建(第八天)(缓冲区、gitee提交)
  • 让 AI 更智能的检索增强生成(Retrieval-Augmented Generation)
  • 组态软件之万维组态介绍(web组态、html组态、vue2/vue3组态、组态软件、组态编辑器)
  • Redis 集群配置
  • 代码随想录算法训练营Day12 | Leetcode 226翻转二叉树、101对称二叉树、104二叉树的最大深度、111二叉树的最小深度
  • PHP框架 ThinkPHP 漏洞探测分析
  • 基于SpringBoot+Vue的在教务管理(课程管理)系统+LW示例
  • 技术迭代、流量困境与营销突破:基于开源AI大模型与S2B2C模式的创新路径研究
  • HCIA-AI人工智能笔记4:神经网络类型
  • SpringSecurity + OAuth2 限制一个用户(同端互斥)登录
  • c# winform 提高界面加载速度
  • 毕设知识点
  • 图解AUTOSAR_SWS_UDPNetworkManagement
  • 探索抓包利器ProxyPin,实现手机APP请求抓包,支持https请求
  • Pyecharts入门之绘制地图数据
  • 基于赛灵思 Xilinx RFSoC 的 VPX 6U 高速数据采集模块技术讨论
  • 夜读丨为萤火虫哭泣的夜晚
  • 广西壮族自治区党委常委会:坚决拥护党中央对蓝天立进行审查调查的决定
  • 美国关税压力下,日本经济一年来首次萎缩
  • 河南信阳:对违规吃喝问题不遮丑不护短,露头就打、反复敲打
  • 最高人民法院、中国证监会联合发布《关于严格公正执法司法 服务保障资本市场高质量发展的指导意见》
  • 联合国第二届运动会闭幕,刘国梁受邀成为“联合国运动会大使”