2

から継承するクラスweaponprojectileクラス、およびクラス があり、クラスはから継承し、クラスには武器の発射体を取得および設定する発射体プロパティがあります。ballistic weaponweaponballistic projectileprojectileweapon

弾道兵器はこれを継承しますが、弾道兵器には弾道発射体を持つ武器だけはありません(即時の影響であるため発射速度を持たないレーザー発射体とは異なります)

したがって、武器のプロパティをオーバーライドすることを選択すると、セッターが問題を引き起こす可能性があります。

public Projectile weaponprojectile
{
// getter/setter
}

一般的な発射物だけを取ります。ゲッターのオーバーライドは問題なく機能します。これは、balltic 発射体を返すと基本の発射体が返されるためです。しかし、セッターは絶対に大丈夫ではありません。弾道発射体として設定できる発射体だけではありません。

したがって、オーバーライドを使用する場合、弾道および静的変換のタイプを確認するのは正しい方法ですか、それとも何か他のことを試す必要がありますか?

オーバーライドを使用せずに新しいセッターを作成すると、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 メソッド (または、weaponprojectile を使用するメソッド) があると思います。おそらくそのメソッドをオーバーライドしたいと思うでしょう。タイプを検出してアクションを実行する必要があるのは、最適な設計ではありません。変更内容 (この場合は 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 に答える