重写继承的属性,如果更具体,则创建一个新属性
本文关键字:属性 新属性 一个 创建 继承 如果 重写 | 更新日期: 2023-09-27 18:11:31
我有一个weapon
类,projectile
类和ballistic weapon
类继承自weapon
, ballistic projectile
类继承自projectile
, weapon
类有一个炮弹属性,用于获取和设置武器的炮弹。
弹道武器继承了这一点,但弹道武器不会有任何武器它有一个弹道弹丸(不同于激光弹丸,激光弹丸不会有弹丸速度,因为它是即时撞击)
所以如果我选择重写武器的属性,setter可能会导致问题,因为
public Projectile weaponprojectile
{
// getter/setter
}
只需要一个一般的抛射体。getter重写会工作得很好因为返回一个弹道抛射仍然是返回一个基础抛射,它有抛射所做的所有事情。然而setter并不是绝对正确的。并不是所有的弹丸都可以被设定为弹道弹丸。
所以,如果我使用重写是正确的方式来确认类型的弹道和静态转换,还是我应该尝试其他东西?
如果我不使用重写,而是创建一个新的setter,我担心我最终会得到这个有两个几乎相同属性的武器,
它的抛射物和它的弹道抛射物基本上是抛射物加上一些其他的东西,真正拥有一个弹道抛射物是没有意义的。
我刚开始使用继承,所以如果有人能给我一些基本的指导,如果你有一个具有泛型变量的抽象类,你继承了这个类和变量,并有一个更具体的变量类型,你该怎么做
你可以使用协方差来允许武器属性中的"专一化"射弹,同时仍然保持将武器视为同一层次结构的一部分的能力:
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);
}
}
有很多方法可以设计你想要的东西。如果是我,我可能会使用接口来避免您所描述的继承问题。我还可以在运行时加载的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;
}
}
}
您可能需要发布所有涉及的类。如果我理解你的话,我会认为你在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
}
}