Override inherited property or make a new one if more specific?
我有一个
弹道武器继承了这个,但是弹道武器不会只有任何武器它有一个弹道弹丸(不同于激光弹丸,因为它是瞬间撞击,所以没有弹丸速度)
所以如果我选择覆盖武器的属性,设置者可能会导致问题,因为
1 2 3 4 | public Projectile weaponprojectile { // getter/setter } |
只需要一个普通的抛射体。吸气剂覆盖将工作正常,因为返回一个弹丸仍然返回一个基本的抛射,它有抛射物做的所有事情,然后一些。不过,二传手肯定不太好。不仅仅是任何炮弹都可以作为弹道导弹。
因此,如果我使用覆盖,是确认弹道和静态转换类型的正确方法,还是应该尝试其他方法?
如果我不使用超控,而是制造一个新的二传手,我担心我最终会得到这个武器,它有两个几乎相同的属性,
它的弹丸和它的弹道弹丸,基本上是一个弹丸加上一些其他的东西,真正有一个得到弹道弹丸是毫无意义的。
我刚开始使用继承,所以如果有人能给我一些基本的指导,如果你有一个带有通用变量的抽象类,你继承了这个类和变量,并且有一个更具体的变量类型,你该怎么做。
您可以使用协方差来允许武器属性中的"特殊"射弹,同时仍然保持将武器视为同一层次的一部分的能力:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 } } |
有很多方法可以设计你想要的东西。如果是我,我可能会利用接口来避免您描述的继承问题。我还可以在运行时加载的XML文件中描述这些不同类型的武器。然而,类似这样的事情会基于您所描述的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | 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; } } } |