亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

c#中繼承相同接口得到的相似代碼有沒有好的解耦方法?

c#中繼承相同接口得到的相似代碼有沒有好的解耦方法?

C#
catspeake 2023-04-29 16:37:23
比方說,在代碼中,我們有一個 IEnemy 接口,它有一個名為 Attack() 的方法。假設我們有五個派生自 IEnemy 接口的敵人。在其中三個類中,我們使用完全相同的 Attack 方法實現。在其中一個中,我們也使用相同的代碼,但在方法的某處更改了一兩行代碼。而且,在上一節課中,我們仍然有相同的實現,但在方法的某處添加/刪除了一兩行代碼。您對解耦這段代碼有什么建議嗎?如果我們在方法中間更改某些內容,我已經嘗試覆蓋不起作用的方法。我嘗試使用委托作為參數,當我們想要更改方法中其他地方的某些內容時,它不起作用。我嘗試使用接口的擴展方法來創建默認實現,但其中兩個類仍然具有解耦代碼。interface IEnemy{    void Attack();}class Enemy1 : IEnemy{    public void Attack()    {        Console.WriteLine("This is an enemy");        Console.WriteLine("Enemy is jumping");        Console.WriteLine("Enemy is attacking");    }}class Enemy2 : IEnemy{    public void Attack()    {        Console.WriteLine("This is an enemy");        Console.WriteLine("Enemy is jumping");        Console.WriteLine("Enemy is attacking");    }}class Enemy3 : IEnemy{    public void Attack()    {        Console.WriteLine("This is an enemy");        Console.WriteLine("Enemy is jumping");        Console.WriteLine("Enemy is attacking");    }}//Let's say this enemy is not capable of jumping, so we want to remove the code that says enemy is jumping.class Enemy4 : IEnemy{    public void Attack()    {        Console.WriteLine("This is an enemy");        Console.WriteLine("Enemy is attacking");    }}//Let's say this is the boss and instead of jumping, it will roar.//So we want to change the code that says enemy is jumping to enemy is roaring.class Enemy5 : IEnemy{    public void Attack()    {        Console.WriteLine("This is an enemy");        Console.WriteLine("Enemy is roaring");        Console.WriteLine("Enemy is attacking");    }}
查看完整描述

2 回答

?
神不在的星期二

TA貢獻1963條經驗 獲得超6個贊

我會將接口替換為具有默認實現的抽象基類,然后將Attack方法分解為單獨的可重寫步驟。我Attack為完全擁有自己的攻擊模式的敵人制作了虛擬。


abstract class BaseEnemy {

    public virtual void Attack() {

        AttackIdentify();

        AttackSignal();

        AttackAttack();

    }


    protected virtual void AttackIdentify() {

        Console.WriteLine("This is an enemy");

    }


    protected virtual void AttackSignal() {

        Console.WriteLine("Enemy is jumping");

    }


    protected virtual void AttackAttack() {

        Console.WriteLine("Enemy is attacking");

    }

}


class Enemy1 : BaseEnemy {

    protected override void AttackIdentify() {

        Console.WriteLine("This is an enemy 1");

    }

}


class Enemy2 : BaseEnemy {

}


class Enemy3 : BaseEnemy {

    protected override void AttackIdentify() {

        Console.WriteLine("This is an enemy 3");

    }

}


//Let's say this enemy is not capable of jumping, so we want to remove the code that says enemy is jumping.

class Enemy4 : BaseEnemy {

    protected override void AttackSignal() { }

}


//Let's say this is the boss and instead of jumping, it will roar.

//So we want to change the code that says enemy is jumping to enemy is roaring.

class Enemy5 : BaseEnemy {

    protected override void AttackSignal() {

        Console.WriteLine("Enemy is roaring");

    }

}

如果您仍然需要該接口IEnemy,則可以BaseEnemy實現它。


查看完整回答
反對 回復 2023-04-29
?
HUWWW

TA貢獻1874條經驗 獲得超12個贊

這是它的抽象類版本的基本示例。


public abstract class Enemy

{

    public bool CanJump { get; set; } = false;

    public bool CanRoar { get; set; } = false;

    public bool CanAttack { get; set; } = false;


    public virtual void Attack()

    {

        Console.WriteLine("This is an enemy");


        if (CanJump)

        {

            Console.WriteLine("Enemy is jumping");

        }


        if (CanRoar)

        {

            Console.WriteLine("Enemy is roaring");

        }


        if (CanAttack)

        {

            Console.WriteLine("Enemy is attacking");

        }

    }

}


public class Enemy1 : Enemy

{

    public Enemy1()

    {

        CanJump = true;

        CanRoar = true;

    }

}


public class Enemy2 : Enemy

{

    public Enemy2()

    {

        CanRoar = true;

        CanAttack = true;

    }

}


public class Enemy3 : Enemy

{

    public Enemy3()

    {

        CanRoar = true;

        CanAttack = true;

    }


    public override void Attack()

    {

        base.Attack();


        Console.WriteLine("Custom thing");

    }

}

您會注意到并Enemy1以Enemy2相同的方式工作,但設置不同的屬性,當您調用該Attack方法時,這些屬性將相應顯示。我希望您注意的有趣部分是Enemy3覆蓋該方法的類。Virtual這可以通過在抽象類中創建方法來實現Enemy。


此覆蓋允許仍然調用Attack類中的基類方法Enemy,而且它還顯示自定義值。所以它非常靈活。


請注意,這對于提供的示例非常有效,但是通過使用您的類名,我可以輕松地假設真正的項目是什么,這不是正確的方法。您不應該為每個敵人創建一個不同的類,但這超出了問題的范圍。


查看完整回答
反對 回復 2023-04-29
  • 2 回答
  • 0 關注
  • 178 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號