【问题标题】:Polymorphism without implementing all virtual methods不实现所有虚方法的多态性
【发布时间】:2021-11-25 06:22:21
【问题描述】:

在使用多态性时,在所有派生类中实现虚方法是否被认为是一种不好的编程习惯?

假设我有一个 Enemy 类和几个派生类。所有的敌人类型都有一个 Attack() 方法,但只有一部分能够跳跃。在这种情况下,除了兽人之外的所有敌人都有跳跃技能。

using System;

namespace Polymorphism
{
    class Program
    {
        static void Main()
        {
            Enemy enemy1 = new Spider();
            Enemy enemy2 = new Goblin();
            Enemy enemy3 = new Orc();
        }
    }

    abstract class Enemy
    {   
        //I'm making this abstract because all derived classes will implement this anyway
        public abstract void Attack();

        //This is virtual because not all derived enemy types can jump
        public virtual void Jump()
        {
            //nothing here
        }
    }
   

    class Spider : Enemy
    {
        public override void Attack()
        {
            Console.WriteLine("Bite attack!");
        }

        public override void Jump()
        {
            Console.WriteLine("Spider jump animation");
        }
    }

    class Goblin : Enemy
    {
        public override void Attack()
        {
            Console.WriteLine("Arrow attack!");
        }

        public override void Jump()
        {
            Console.WriteLine("Goblin jump animation");
        }
    }

    class Orc : Enemy
    {
        public override void Attack()
        {
            Console.WriteLine("Axe attack!");
        }

        //no jump method here! 
    }
}

即使兽人不能跳跃,基类的 Jump() 方法仍然可以调用,即使在兽人的情况下它完全没有任何作用。我发现 Intellisense 仍然“推荐”跳转按钮有点误导,而且这对我来说似乎也不是一个好的编程习惯。这是一种不好的方法吗?如果我真的想能够将所有敌人的对象放在同一个数组中,那么还有哪些选择?据我所知,您无法真正访问派生类中的非覆盖方法,而且强制转换听起来很麻烦。

【问题讨论】:

  • “你不能真正访问派生类中的非覆盖方法”——从什么时候开始?不过,对于你的问题,我很想考虑要么拥有一个虚拟的 get-only 属性CanJump,要么定义(并在适当的情况下实现)IJumper 接口。
  • 您是否考虑过ISupportsJump(Kangaroo 会实现,但Orc 不会实现)?那么如果你有一个 Enemy 实例 - (enemy as ISupportsJump)?.Jump();
  • 我不认为 Intellisense 聪明地知道何时需要添加这样的缺失操作。我不会在这里听。

标签: c# polymorphism overriding virtual


【解决方案1】:

您可以访问基类中除私有之外的任何方法。试试这个

abstract class BaseEnemy
{
    //I'm making this abstract because all derived classes will implement this anyway
    public abstract void Attack();
    
}

abstract class AdvancedEnemy:BaseEnemy
{
    
    //This is virtual because not all derived enemy types can jump
    public virtual void Jump()
    {

    }

}


class Spider : AdvancedEnemy
{
    public override void Attack()
    {
        Console.WriteLine("Bite attack!");
    }

    public override void Jump()
    {
        Console.WriteLine("Spider jump animation");
    }
}

class Goblin :  AdvancedEnemy
{
    public override void Attack()
    {
        Console.WriteLine("Arrow attack!");
    }

    public override void Jump()
    {
        Console.WriteLine("Goblin jump animation");
    }
}

class Orc : BaseEnemy
{
    public override void Attack()
    {
        Console.WriteLine("Axe attack!");
    }

    

    //no jump method here! 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    相关资源
    最近更新 更多