1. 程式人生 > >專案實戰中如何使用抽象類和介面

專案實戰中如何使用抽象類和介面

引子:

時常會有這麼一個疑惑,抽象類和介面功能好像,真正用起來該如何抉擇呢??

好問題。。

來看看書上怎麼說的(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