博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#语法-虚方法详解 Virtual 虚函数
阅读量:7080 次
发布时间:2019-06-28

本文共 4346 字,大约阅读时间需要 14 分钟。

虚方法 / Virtual


本文提供全流程,中文翻译。
Chinar 坚持将简单的生活方式,带给世人!
(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)


Chinar —— 心分享、心创新!
助力快速理解 虚方法 的用法
为新手节省宝贵的时间,避免采坑!


全文高清图片,点击即可放大观看 (很多人竟然不知道)


1

Virtual Method —— 虚方法

这里我们来详细说说: 虚方法/虚函数

通过简单的例子,来说明虚方法是个什么东西

虚方法,可以理解为 “一个不完整”/“可以扩展” 的方法

Virtual (虚)与 Override (重写) 是同时出现的

在子类中,重写 Override (重写)虚方法时,父类中的函数才会被重写

在子类中,重写时,写明了 base ,并重写时,子类基于父类函数进行扩展

举个栗子黑白88
3个子类,同时继承一个父类

那么父类中的函数,子类都将拥有

用中国的老话 “推翻重来”理解,很是合适

base 后可以理解为: 老子会什么,儿子通过努力(重写),比老子会的更多/会的不一样


2

Parent Class:Enemy —— 父类:总敌人类

我们以控制台程序,来举个例子

Enemy —— 敌人类,可以包含很多种敌人的,父类/总类

我们在其中写一些,普通方法 以及 虚方法

举个栗子黑白88

using System;/// /// 这里明明空间用中文,便于新手理解(请不要学我)/// namespace 虚方法{    ///     /// 敌人大类    ///     class Enemy    {        ///         /// 普通方法:智能系统        ///         public void Ai()        {            Console.WriteLine("父类怪物智能系统");            Move();        }        ///         /// 虚方法:移动        ///         public virtual void Move()        {            Console.WriteLine("父类怪物移动方法");        }        ///         /// 虚方法:打脸        ///         public virtual void 打脸()        {            Console.WriteLine("父类打脸");        }        private float hp;        private float speed;        public float Speed //速度        {            get { return speed; }            set { speed = value; }        }        public float Hp //血量        {            get { return hp; }            set { hp = value; }        }    }}

3

Subclass:Boss ——子类:首领

Boss —— 首领:属于怪物的一种,同样属于敌人,所以可以继承 Enemy 敌人类

new 关键字,由于子类中 Move 函数名,与父类中 Move 函数名相同

所以用 new 关键词修饰,用以区分,并隐藏父类中 Move 方法

举个栗子黑白88

using System;namespace 虚方法{    ///     /// 首领:也属于敌人 所以继承敌人类    ///     class Boss : Enemy    {        //子类里重写虚函数后,不论在哪里调用,都是调用重写后的 Move方法        //例如 Boss b=new Boss(); b.Ai()调用的Move方法,就是重写虚函数中  下边这个Move方法        //而不是父类中的 Move        public new void Move()        {            Console.WriteLine("这是子类-Boss的移动方法");        }        public void Attack()        {            Console.WriteLine("子类-Boss正在猛烈的摇晃");            Move();        }    }}

4

Subclass:Enemy1、Enemy2 ——子类:敌人1、敌人2

Enemy1、Enemy2 —— 代表两种敌人类型:属于怪物的一种,同样属于敌人,所以可以继承 Enemy 敌人类

当你见到 Override 关键字,你的第一印象就应该想到,这个函数被重写了

当你见到 Override 并且,函数体中包含 base.相同的函数名,那就代表着 :这个函数是基于父类函数重写/扩展的

举个栗子黑白88

using System;namespace 虚方法{    ///     /// 第一种敌人    ///     class Enemy1 : Enemy    {        ///         /// 这里因为没有 base,所以子类中的Move 就是下面一句代码        /// 父类中的Move,在当前类中就不存在了。因为在子类中重写了        ///         public override void Move()        {            Console.WriteLine("这是子类-Enemy1的移动方法");        }    }    ///     /// 第二种敌人    ///     class Enemy2 : Enemy    {        ///         /// 重写 Move 移动函数        ///         public override void Move()        {            base.Move();                           //base. —— 在原有的基础上,新增方法(也就是进行扩展,父类的函数体 依旧具备)            Console.WriteLine("这是子类-Enemy2的移动方法"); //从之类往下写,就是子类新增的函数体        }    }}

5

Test Main ——主入口:测试

Enemy1、Enemy2 —— 代表两种敌人类型:属于怪物的一种,同样属于敌人,所以可以继承 Enemy 敌人类

这样,不用再 Enemy1、Enemy2 类中写任何方法,默认两种怪物,就具备敌人通用的所有属性 / 函数

举个栗子黑白88

using System;namespace 虚方法{    ///     /// 测试虚函数    ///     class Program    {        static void Main(string[] args)        {            Enemy enemy = new Enemy();            enemy.Ai();            Console.WriteLine("..........................");            Enemy e = new Boss(); //敌人大类对象,用boss构造 由于子类中没有重写父类方法            e.Ai();               //所以调用的还是父类中的隐藏方法            e.Move();            Console.WriteLine("..........................");            Enemy e1 = new Enemy1(); //敌人大类对象,用子类 Enemy1 构造,由于子类中重写了父类方法            e1.Ai();                 //所以调用的时候,父类的Move()方法,是子类重写一个后的方法。            e1.Move();            Console.WriteLine("..........................");            Enemy e2 = new Enemy2();            e2.Ai();            e2.Move();            Console.WriteLine("..........................");            Console.ReadLine();        }    }}

输出结果:

父类怪物智能系统父类怪物移动方法..........................父类怪物智能系统父类怪物移动方法父类怪物移动方法..........................父类怪物智能系统这是子类-Enemy1的移动方法这是子类-Enemy1的移动方法..........................父类怪物智能系统父类怪物移动方法这是子类-Enemy2的移动方法父类怪物移动方法这是子类-Enemy2的移动方法..........................

这里写图片描述


支持

May Be —— 搞开发,总有一天要做的事!

拥有自己的服务器,无需再找攻略!
Chinar 提供一站式教程,闭眼式创建!
为新手节省宝贵时间,避免采坑!

1 ——
2 ——
3——
4 ——


70
Chinar


END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

转载于:https://www.cnblogs.com/chinarbolg/p/9601398.html

你可能感兴趣的文章
C++STL之二叉堆
查看>>
华为5700系列作DHCP Server的配置
查看>>
C++STL之堆排序算法
查看>>
安装KVM虚拟机并管理
查看>>
linux 单网卡绑定多IP及BONGDING的实现
查看>>
java 多线程—线程怎么来的?
查看>>
tomcat环境下服务器文件句柄耗尽(Too Many Open Files)的问题排查
查看>>
NPOI操作excel——利用反射机制,NPOI读取excel数据准确映射到数据库字段
查看>>
为什么要选择云计算?
查看>>
SSL/TLS协议详解
查看>>
我的友情链接
查看>>
使用开源组件slidingmenu_library来模拟实现人人客户端的主页侧滑界面
查看>>
Struts2学习笔记(七)之文件的下载
查看>>
我的友情链接
查看>>
一生都学不完的计谋
查看>>
Linu之sed用法
查看>>
闲言碎语
查看>>
Docker 安装 Python
查看>>
FTP(IIS6.0)的搭建与配置
查看>>
Linux上Qt5运行时缺少一些组件产生的错误的解决方案
查看>>