專案實戰中如何使用抽象類和介面
引子:
時常會有這麼一個疑惑,抽象類和介面功能好像,真正用起來該如何抉擇呢??
好問題。。
來看看書上怎麼說的(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