如果更具体,覆盖继承的属性或创建一个新属性?

时间:2013-04-30 04:27:41

标签: c#

我有一个weapon类,projectile类和ballistic weapon类继承自weaponballistic projectile类继承自projectile和{ {1}}类具有射弹属性,可以获取和设置武器的射弹。

弹道武器继承了这一点,但弹道武器不会有任何武器 它有一个弹道射弹(不同于激光射弹,不会有射弹速度,因为它是瞬间撞击)

因此,如果我选择覆盖武器的属性,则设置器可能会导致问题,因为

weapon

只需要一个通用的弹丸。吸气器覆盖可以正常工作,因为返回一个弹道炮弹仍然返回一个基础射弹,它具有抛射物所做的所有东西,然后是一些。然而,制定者并不是绝对可以的。不仅任何射弹都可以设置为弹道射弹。

所以,如果我使用覆盖,它是确认弹道和静态转换类型的正确方法,还是我应该尝试别的?

如果我不使用覆盖但是做一个新的制定者,我担心我最终会得到这种具有两个近似属性的武器,

它的射弹和它的弹道射弹基本上是一个抛射物加上其他一些东西而且真的有一个弹道弹是无意义的。

我是新手使用继承所以如果你有一个带有泛型变量的抽象类并且你继承了那个类和变量并且有一个更具体的变量类型,那么如果有人可以给我指导你基本上做什么。

3 个答案:

答案 0 :(得分:2)

你可以使用covariance来允许武器属性中的“专门”射弹,同时仍然能够将武器视为同一层次结构的一部分:

interface IProjectile {
    string Name { get; }
}

// Note the `out` keyword below:
interface IWeapon<out TProjectile> where TProjectile : IProjectile {
    TProjectile Projectile { get; }
}

class BallisticMissile : IProjectile {
    public double Speed { get; set; }
    public string Name { get { return "ballistic missile"; } }
}

class BallisticWeapon : IWeapon<BallisticMissile> {
    public BallisticMissile Projectile { get; set; }
}

class LaserBeam : IProjectile {
    public double WaveLength;
    public string Name { get { return "laser beam"; } }
}

class LaserWeapon : IWeapon<LaserBeam> {
    public LaserBeam Projectile { get; set; }
}

class Program {

    static void Main(string[] args) {

        // Manipulate the ballistic weapon in its own specific way:
        var ballisticWeapon = new BallisticWeapon();
        ballisticWeapon.Projectile = new BallisticMissile();
        ballisticWeapon.Projectile.Speed = 2000;

        // Manipulate the laser weapon in its own specific way:
        var laserWeapon = new LaserWeapon();
        laserWeapon.Projectile = new LaserBeam();
        laserWeapon.Projectile.WaveLength = 400;

        // But you can still use both of them as an IWeapon<IProjectile>:
        var weapons = new List<IWeapon<IProjectile>>();
        weapons.Add(ballisticWeapon);
        weapons.Add(laserWeapon);
        foreach (var weapon in weapons)
            Console.WriteLine(weapon.Projectile.Name);

    }

}

答案 1 :(得分:1)

有很多方法可以设计您想要的东西。如果是我,我可能会使用接口来避免你描述的继承问题。我也可以在运行时加载的xml文件中描述这些不同类型的武器。但是,这样的事情将根据你所描述的内容起作用:

public interface IWeapon
    {
        int WeaponDamage { get; }
    }

    public interface IBalisticWeapon
    {
        int BallisticDamage { get; }
    }

    public interface IProjectile
    {
        int ProjectileDamage { get; }
    }

    public abstract class WeaponBase: IWeapon
    {
        public virtual int WeaponDamage { get { return 100; } }//base damage
    }

    public class Arrow : WeaponBase, IProjectile, IBalisticWeapon
    {
        public override int WeaponDamage { get { return this.BallisticDamage; } }

        public int BallisticDamage { get { return 10; } }

        public int ProjectileDamage { get { return this.BallisticDamage; } }
    }

    public class BattleAxe : WeaponBase
    {
        //this inherits Weapon Damage from WeaponBase
    }

    public class Rock : WeaponBase, IProjectile
    {
        public override int WeaponDamage { get { return this.ProjectileDamage; } }
        public int ProjectileDamage { get { return 10; } }
    }

    class Program
    {
        static WeaponBase GetWeapon()
        {
            return new Arrow();
        }

        static void Main(string[] args)
        {
            int damage = 0;
            IWeapon weapon = GetWeapon();
            if (weapon is IProjectile)
            {
                damage = (weapon as IProjectile).ProjectileDamage;
            }
            else if (weapon is IBalisticWeapon)
            {
                damage = (weapon as IBalisticWeapon).BallisticDamage;
            }
            else
            {
                damage = (weapon as IWeapon).WeaponDamage;
            }
        }
    }

答案 2 :(得分:1)

您可能希望发布所有涉及的课程。如果我理解你,我会认为你在Weapon类中有一些Fire方法(或者某些使用武器弹丸的方法)。您可能想要覆盖该方法。必须检测类型并采取行动不是最好的设计。最好封装一些更改(在这种情况下是执行Fire / Attack / Whatever的代码)和Setter。实施例

public class BalisticWeapon
{
  public BalisticWeapon(){}

  public override BalisticProjectile weaponprojectile
  {
    get { return Base.weaponprojectile; }
    set { Base.Weaponprojectile = value; }
  }

  public override void Fire()
  {
    //Handle special case for Firing BalisticProjectile
  }
}