• C#语法-虚方法详解 Virtual 虚函数


    虚方法 / Virtual


    本文提供全流程,中文翻译。

    Chinar 坚持将简单的生活方式,带给世人!

    (拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)



    Chinar —— 心分享、心创新!

    助力快速理解 虚方法 的用法

    为新手节省宝贵的时间,避免采坑!



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


    1

    Virtual Method —— 虚方法


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

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

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

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

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

    在子类中,重写时,写明了 base ,并重写时,子类基于父类函数进行扩展
    举个栗子黑白88
    3个子类,同时继承一个父类

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

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

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


    2

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


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

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

    我们在其中写一些,普通方法 以及 虚方法
    举个栗子黑白88

    using System;
    
    /// <summary>
    /// 这里明明空间用中文,便于新手理解(请不要学我)
    /// </summary>
    namespace 虚方法
    {
        /// <summary>
        /// 敌人大类
        /// </summary>
        class Enemy
        {
            /// <summary>
            /// 普通方法:智能系统
            /// </summary>
            public void Ai()
            {
                Console.WriteLine("父类怪物智能系统");
                Move();
            }
    
    
            /// <summary>
            /// 虚方法:移动
            /// </summary>
            public virtual void Move()
            {
                Console.WriteLine("父类怪物移动方法");
            }
    
    
            /// <summary>
            /// 虚方法:打脸
            /// </summary>
            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 虚方法
    {
        /// <summary>
        /// 首领:也属于敌人 所以继承敌人类
        /// </summary>
        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 虚方法
    {
        /// <summary>
        /// 第一种敌人
        /// </summary>
        class Enemy1 : Enemy
        {
            /// <summary>
            /// 这里因为没有 base,所以子类中的Move 就是下面一句代码
            /// 父类中的Move,在当前类中就不存在了。因为在子类中重写了
            /// </summary>
            public override void Move()
            {
                Console.WriteLine("这是子类-Enemy1的移动方法");
            }
        }
    
    
        /// <summary>
        /// 第二种敌人
        /// </summary>
        class Enemy2 : Enemy
        {
            /// <summary>
            /// 重写 Move 移动函数
            /// </summary>
            public override void Move()
            {
                base.Move();                           //base. —— 在原有的基础上,新增方法(也就是进行扩展,父类的函数体 依旧具备)
                Console.WriteLine("这是子类-Enemy2的移动方法"); //从之类往下写,就是子类新增的函数体
            }
        }
    }

    5

    Test Main ——主入口:测试


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

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

    using System;
    
    
    namespace 虚方法
    {
        /// <summary>
        /// 测试虚函数
        /// </summary>
        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 —— 阿里ECS云服务器自定义配置 - 购买教程(新手必备!)

    3—— Windows 服务器配置、运行、建站一条龙 !

    4 —— Linux 服务器配置、运行、建站一条龙 !





    Chinar


    END

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

    对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com

    对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

  • 相关阅读:
    java.lang.NoClassDefFoundError: org/apache/poi/ss/formula/udf/UDFFinder
    IntelliJ使用指南—— 深入了解IntelliJ的Web部署逻辑
    javascript深入理解js闭包
    git commit -F时用到的commit.log模板
    github上需要生成密钥对:ssh key
    windows和linux字体库位置
    .vimrc配置文件
    iw交叉编译
    libnl和libopenssl,hostapd交叉编译
    linux中断
  • 原文地址:https://www.cnblogs.com/chinarbolg/p/9601398.html
Copyright © 2020-2023  润新知