Я застрял в этой ситуации, когда:
- У меня есть абстрактный класс
Ammo, сAmmoBoxиClipкак дети. - У меня есть абстрактный класс, называемый
Weapon, сFirearmиMeleeкак дети. -
Firearmявляется абстрактным, сClipWeaponиShellWeaponкак дети. - Внутри
Firearmестьvoid Reload(Ammo ammo);
Проблема заключается в том, что a ClipWeapon может использовать как Clip, так и 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));
}
}
Но a ShellWeapon может использовать только AmmoBox для перезагрузки. Я мог бы сделать это:
public override void Reload(Ammo ammo)
{
if (ammo is AmmoBox)
{
// reload...
}
}
Но это плохо, потому что, несмотря на то, что я проверяю, что это тип AmmoBox, снаружи, он выглядит как ShellWeapon может принимать Clip, так как a Clip также Ammo.
Или, я мог бы удалить Reload из Firearm и поместить его как ClipWeapon и ShellWeapon с конкретными параметрами, которые мне нужны, но при этом я потеряю преимущества полиморфизма, что не то, что я хотите.
Не было бы это оптимальным, если бы я мог переопределить Reload внутри ShellWeapon следующим образом:
public override void Reload(AmmoBox ammoBox)
{
// reload ...
}
Конечно, я попробовал, и это не сработало, я получил сообщение об ошибке, что подпись должна соответствовать или что-то в этом роде, но разве это не должно быть "логически"? так как AmmoBox есть Ammo?
Как мне обойти это? И вообще, мой дизайн правильный?
(Обратите внимание, что я использовал интерфейсы IClipWeapon и IShellWeapon, но у меня возникли проблемы, поэтому я перешел на использование классов)
Спасибо заранее.