zoukankan      html  css  js  c++  java
  • 项目实战中如何使用抽象类和接口

    引子:

    时常会有这么一个疑惑,抽象类和接口功能好像,真正用起来该如何抉择呢??

    好问题。。

    来看看书上怎么说的(C#7.0本质论)

    虽然方法可在基类中声明为抽象成员,但是!!如果都从一个基类派生,会用掉唯一的基类机会,(什么意思呢:也就是C#的单继承特性了),所以,什么都往基类里面加,就会显得特别臃肿,且不通用。

    所以,原则就是:大共性你给我放基类,小共性用接口。

    举个例子:一个动物基类(包含动物叫、动物吃放、动物睡觉) --  这都没问题!!

    但是你给动物的基类里面加一个动物飞行(虽然动物里面的鸟、鸡等都可以飞,但是喵和狗你怎么飞啊),所以,这个加的就很不理智,虽然也是个共性,但是个小共性。

    所以,这个小共性用接口实现就非常的Nice,为何呢(因为C#是单继承多接口啊!),也就是说,你的狗子不会飞就不要来接触这个接口咯,会飞的动物,除了继承基类,再加个接口就OK了。

    正文:

    还是基于游戏,我想到了一个场景,就借这个场景来实战一下吧。

    场景描述:

    1、三个人(剑士、奶妈、格斗家)组团刷副本

    2、三个人的大共性有三条(移动、攻击、聊天)

    3、奶妈的可以加团体Buff和团体回血

    4、格斗家可以加团体Buff

    5、剑士可以加自身Buff

    这时候呢:很显然就把移动、打怪、聊天设置为基类了;而剩下的则以接口出现,当然至于为什么要用接口,可以看上一篇关于抽象类的文章,道理差不多。

    第一步:先定义一个基类(三个职业共性)

        public class Abstract
        {
            public abstract class AbstractAction
            {
                public abstract void Action();
            }
    
            public class Move : AbstractAction
            {
                public override void Action()
                {
                    // 英雄移动
                    Console.WriteLine("正在移动");
                }
            }
    
            public class Attack : AbstractAction
            {
                public override void Action()
                {
                    // 英雄攻击
                    Console.WriteLine("开始打怪");
                }
            }
    
            public class Call : AbstractAction
            {
                public override void Action()
                {
                    // 聊天
                    Console.WriteLine("Hi、妹子...");
                }
            }
        }

    第二部:定义两个接口(回血和加Buff)

        interface IAddMilk
        {
            void AddMilk();
        }
    
        interface IAddBuff
        {
            void AddBuff();
        }

    第三部:定义三个英雄

       剑士(调用加Buff接口):

        public class Swordsman : IAddBuff
        {
            private AbstractAction action;
    
            public Swordsman() { }
    
            public void Select(AbstractAction action)
            {
                this.action = action;
            }
    
            public void Go()
            {
                action.Action();
            }
    
            public void AddBuff()
            {
                Console.WriteLine("我只给自己加Buff");
            }
        }

        格斗家(调用加Buff接口):

        public class Fighter : IAddBuff
        {
            private AbstractAction action;
    
            public Fighter() { }
    
            public void Select(AbstractAction action)
            {
                this.action = action;
            }
    
            public void Go()
            {
                action.Action();
            }
    
            public void AddBuff()
            {
                Console.WriteLine("我给团体加Buff");
            }
        }

        奶妈(调用加Buff和加奶接口):

        public class Nanny : IAddBuff,IAddMilk
        {
            private AbstractAction action;
    
            public Nanny() { }
    
            public void Select(AbstractAction action)
            {
                this.action = action;
            }
    
            public void Go()
            {
                action.Action();
            }
    
            public void AddBuff()
            {
                Console.WriteLine("我给团体加Buff");
            }
    
            public void AddMilk()
            {
                Console.WriteLine("我给团体回血");
            }
        }

    第四部:实例化三个职业并完成以下功能:

    奶妈进图加Buff、加血、顺便和格斗家姑娘打个招呼;格斗家加上团体Buff开始打怪;剑士加上个人Buff开始打怪。

            static void Main(string[] args)
            {
                // 实例化一个名叫小明的奶妈并进行加Buff和回血,顺便还打了一声招呼
                Nanny cat = new Nanny();
                Console.WriteLine("我是奶妈小明");
                cat.AddBuff();
                cat.AddMilk();
                cat.Select(new Call());
                cat.Go();
    
                Console.WriteLine("------------");
    
                // 实例化一个名叫小强的格斗家,先加个团体Buff,再攻击小怪
                Console.WriteLine("我是副C小强");
                Fighter SmallC = new Fighter();
                SmallC.AddBuff();
                SmallC.Select(new Attack());
                SmallC.Go();
    
                Console.WriteLine("------------");
    
                // 实例化一个主C小帅,先给自己加个Buff,然后打怪。
                Console.WriteLine("我是主C");
                Swordsman xuxubaobao = new Swordsman();
                xuxubaobao.AddBuff();
                xuxubaobao.Select(new Attack());
                xuxubaobao.Go();
    
            }

    实现:

    实验代码:https://github.com/TNever/Interfaceandabstract.git

    我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1fcd4mnz7gs4q

  • 相关阅读:
    解决无线打印机休眠后掉线无法进行局域网打印的问题
    快速为某个目录的verilog文件生成filelist
    使用Visual Studio的Spy++查找弹窗广告进程
    【转载】verilog语法之generate语句的基本认识
    补码(为什么按位取反再加一):告诉你一个其实很简单的问题
    【转载】EDID的简介和解析
    win32diskimager 谨慎使用
    UXE的一些使用归纳
    如何在win8或win10系统里添加inf驱动程序
    STM32 USB HID
  • 原文地址:https://www.cnblogs.com/WeiMLing/p/11396646.html
Copyright © 2011-2022 走看看