C# 重写继承的属性,或者如果更具体,则创建新属性?
我有一个C# 重写继承的属性,或者如果更具体,则创建新属性?,c#,C#,我有一个武器类,射弹类和弹道武器类继承自武器,弹道弹丸类继承自射弹,武器类有一个射弹属性,该属性获取并设置武器的射弹 弹道武器继承了这一点,但是弹道武器不会有任何武器 它有一个弹道弹丸(与激光弹丸不同,激光弹丸不会有弹丸速度,因为它是瞬间撞击) 因此,如果我选择覆盖武器属性,setter可能会导致问题,因为 public Projectile weaponprojectile { // getter/setter } 只需要一个普通的射弹。getter覆盖可以正常工作,因为返回一个球型射弹仍然
武器
类,射弹
类和弹道武器
类继承自武器
,弹道弹丸
类继承自射弹
,武器
类有一个射弹属性,该属性获取并设置武器的射弹
弹道武器继承了这一点,但是弹道武器不会有任何武器
它有一个弹道弹丸(与激光弹丸不同,激光弹丸不会有弹丸速度,因为它是瞬间撞击)
因此,如果我选择覆盖武器属性,setter可能会导致问题,因为
public Projectile weaponprojectile
{
// getter/setter
}
只需要一个普通的射弹。getter覆盖可以正常工作,因为返回一个球型射弹仍然返回一个基础射弹,它拥有射弹所做的所有事情,然后还有一些。然而二传手并不是绝对可以的。不仅仅是任何弹丸都可以被设置为弹道弹丸
所以,如果我使用覆盖,是确认弹道和静态转换类型的正确方法,还是应该尝试其他方法
如果我不使用覆盖,而是制作一个新的setter,我担心我最终会得到这种武器,它有两个几乎相同的属性
它的弹丸和弹道弹丸,基本上是一个弹丸加上一些其他东西,真正拥有一个get弹道弹丸是毫无意义的
我不熟悉使用继承,所以如果有人能给我一些基本的指导,告诉我如果你有一个带有泛型变量的抽象类,你继承了这个类和变量,并且有一个更具体的变量类型,你该怎么做。有很多方法来设计你想要的东西。如果是我,我可能会使用接口来避免您描述的继承问题。我还可以在运行时加载的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;
}
}
}
有很多方法可以设计你想要的东西。如果是我,我可能会使用接口来避免您描述的继承问题。我还可以在运行时加载的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;
}
}
}
您可能希望发布所有涉及的类。如果我理解你,我会认为你在武器类中有一些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
}
}
您可能希望发布所有涉及的类。如果我理解你,我会认为你在武器类中有一些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
}
}
您可以使用以允许在武器属性中使用“专用”射弹,同时仍然能够将武器视为同一层次结构的一部分:
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);
}
}
接口i投影{
字符串名称{get;}
}
//注意下面的'out'关键字:
接口IWeapon,其中tproject:iprojectle{
t投射射弹{get;}
}
类弹道导弹:I射弹{
公共双速{get;set;}
公共字符串名称{get{返回“弹道导弹”;}
}
类弹道武器:IWeapon{
公共弹道导弹射弹{get;set;}
}
激光束类别:I投射{
公共双波长;
公共字符串名称{get{返回“激光束”;}
}
类激光武器:IWeapon{
公共激光束射弹{get;set;}
}
班级计划{
静态void Main(字符串[]参数){
//以特定方式操纵弹道武器:
var弹道武器=新弹道武器();
弹道武器。射弹=新型弹道导弹();
弹道武器.射弹.速度=2000;
//以自己特定的方式操纵激光武器:
var laserWeapon=新的laserWeapon();
laserWeapon.spolution=新的LaserBeam();
激光武器。射弹。波长=400;
//但您仍然可以将这两个组件用作IWeapon:
var武器=新列表();
武器。添加(弹道武器);
武器。添加(激光武器);
foreach(武器中的var武器)
控制台.WriteLine(武器.投射物.名称);
}
}
您可以使用来允许在武器属性中使用“专用”射弹,同时仍然能够将武器视为同一层次结构的一部分:
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);
}
}
接口i投影{
字符串名称{get;}
}
//注意下面的'out'关键字:
接口IWeapon,其中tproject:iprojectle{
t投射射弹{get;}
}
类弹道导弹:I射弹{
公共双速{get;set;}
公共字符串名称{get{返回“弹道导弹”;}
}
类弹道武器:IWeapon{
公共弹道导弹射弹{get;set;}
}
激光束类别:I投射{
公共双波长;
公共字符串名称{get{返回“激光束”;}
}
类激光武器:IWeapon{
公共激光束射弹{get;set;}
}
班级计划{
静态void Main(字符串[]参数){
//以特定方式操纵弹道武器:
var弹道武器=新弹道武器();
弹道武器。射弹=新型弹道导弹();
弹道武器.射弹.速度=2000;
//以自己特定的方式操纵激光武器:
var laserWeapon=新的laserWeapon();
laserWeapon.spolution=新的LaserBeam();
激光