vex*_*exe 13 c# inheritance abstract-class overriding
我陷入了这种情况:
Ammo,有AmmoBox和Clip作为孩子.Weapon,有Firearm和Melee作为孩子.Firearm是抽象的,ClipWeapon和ShellWeapon孩子一样.Firearm,有一个void Reload(Ammo ammo);问题是,a ClipWeapon可以使用a Clip和an AmmoBox来重新加载:
public override void Reload(Ammo ammo)
{
if (ammo is Clip)
{
SwapClips(ammo as Clip);
}
else if (ammo is AmmoBox)
{
var ammoBox = ammo as AmmoBox;
// AddBullets returns how many bullets has left from its parameter
ammoBox.Set(clip.AddBullets(ammoBox.nBullets));
}
}
Run Code Online (Sandbox Code Playgroud)
但是,a ShellWeapon,只能用一个AmmoBox来重装.我能做到这一点:
public override void Reload(Ammo ammo)
{
if (ammo is AmmoBox)
{
// reload...
}
}
Run Code Online (Sandbox Code Playgroud)
但是,因为即使我检查,以确保它的类型,这是不好的AmmoBox,从外面看,它看起来像一个ShellWeapon可能需要Clip为好,因为Clip是Ammo也.
或者,我可以删除Reload从Firearm,并把它都ClipWeapon和ShellWeapon与我所需要的具体参数,可以但这样做我会失去多态性的好处,这不是我想要的.
如果我能像这样覆盖Reload内部,那不是最佳的ShellWeapon:
public override void Reload(AmmoBox ammoBox)
{
// reload ...
}
Run Code Online (Sandbox Code Playgroud)
当然我试过了,它没有用,我收到一个错误,说签名必须匹配或者其他什么,但这不应该是"逻辑上"有效吗?既然AmmoBox是Ammo?
我应该怎么解决这个问题?一般来说,我的设计是否正确?(注意我使用的是接口IClipWeapon,IShellWeapon但是遇到了麻烦,所以我转而使用了类)
提前致谢.
Jon*_*eet 16
但这不应该是'逻辑'有效吗?
不是.您的界面说调用者可以传入任何内容 Ammo - 您限制它需要一个AmmoBox更具体的内容.
如果有人要写,你会发生什么?
Firearm firearm = new ShellWeapon();
firearm.Reload(new Ammo());
Run Code Online (Sandbox Code Playgroud)
?那应该是完全有效的代码 - 所以你想让它在执行时爆炸吗?静态类型的一半是避免这种问题.
你可以做Firearm的弹药类型一般是使用:
public abstract class Firearm<TAmmo> : Weapon where TAmmo : Ammo
{
public abstract void Reload(TAmmo ammo);
}
Run Code Online (Sandbox Code Playgroud)
然后:
public class ShellWeapon : Firearm<AmmoBox>
Run Code Online (Sandbox Code Playgroud)
这可能是也可能不是一种有用的做事方式,但至少值得考虑.
| 归档时间: |
|
| 查看次数: |
8572 次 |
| 最近记录: |