2

我有一个weapon类,projectile类和ballistic weapon继承自的类weaponballistic projectile类继承自projectile并且 weapon类具有获取和设置武器的射弹的射弹属性。

弹道武器继承了这一点,但是弹道武器不会有任何武器,它有弹道弹道(不同于说激光弹道,因为它是即时冲击,所以没有弹道速度)

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

public Projectile weaponprojectile
{
// getter/setter
}

只需要一个通用的 Projectile。吸气剂覆盖可以正常工作,因为返回弹道弹丸仍然返回基础弹丸,它具有弹丸所做的所有事情,然后是一些。然而,二传手不会绝对没问题。不仅仅是任何弹丸都可以设置为弹道弹丸。

因此,如果我使用覆盖是确认弹道和静态转换类型的正确方法,还是应该尝试其他方法?

如果我不使用替代而是制作一个新的二传手,我担心我最终会得到这种具有 2 个几乎相同属性的武器,

它的弹丸和弹道弹丸基本上是弹丸加上其他一些东西,而真正拥有弹道弹丸毫无意义。

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

4

3 回答 3

2

您可以使用协方差来允许武器属性中的“专用”射弹,同时仍然保持将武器视为同一层次结构的一部分的能力:

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);

    }

}
于 2013-04-30T05:09:20.423 回答
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
  }
}
于 2013-04-30T04:56:21.890 回答
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;
            }
        }
    }
于 2013-04-30T04:47:02.417 回答