Sono bloccato in questa situazione in cui:È possibile sovrascrivere un metodo con un parametro derivato anziché uno di base?
- devo una classe astratta denominata
Ammo
, conAmmoBox
eClip
come i bambini. - Ho una classe astratta denominata
Weapon
, conFirearm
eMelee
come bambini. Firearm
è astratto, conClipWeapon
eShellWeapon
come bambini.- All'interno
Firearm
, c'è unavoid Reload(Ammo ammo);
Il problema è che, una ClipWeapon
potrebbe utilizzare sia un Clip
ed un AmmoBox
Per ricaricare:
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));
}
}
Ma un ShellWeapon
, potrebbe utilizzare solo una AmmoBox
a ricaricare. Ho potuto fare questo:
public override void Reload(Ammo ammo)
{
if (ammo is AmmoBox)
{
// reload...
}
}
Ma questo è un male perché, anche se sto controllando per assicurarsi che sia di tipo AmmoBox
, dall'esterno, appare come un ShellWeapon
potrebbe prendere un Clip
così, dal momento che un Clip
è Ammo
pure.
Oppure, potrei rimuovere Reload
da Firearm
, e metterlo sia ClipWeapon
e ShellWeapon
con i params specifici di cui ho bisogno, ma in questo modo io perdo i benefici del polimorfismo, che non è quello che voglio.
Non sarebbe ottimale, se potessi ignorare Reload
all'interno ShellWeapon
come questo:
public override void Reload(AmmoBox ammoBox)
{
// reload ...
}
Naturalmente ho provato e non ha funzionato, ho ottenuto un errore dicendo che la firma deve corrispondere o qualcosa del genere, ma non dovrebbe essere valido 'logicamente'? dal AmmoBox
è un Ammo
?
Come dovrei aggirare questo? E in generale, il mio progetto è corretto? (Nota Stavo usando le interfacce IClipWeapon
e IShellWeapon
ma mi sono imbattuto in problemi, quindi mi sono trasferito a utilizzare invece le classi)
Grazie in anticipo.
Come si può riscrivere la definizione generica che hai scritto, ma per arma da fuoco, invece di Arma? (perché le armi Shell e Clip ereditano direttamente da Firearm e non da Weapon) Ho provato qualcosa del genere ma ovviamente non è così: classe astratta pubblica Firearm dove AmmoType: Munizioni: Arma XD –
vexe
@VeXe: Devi mettere il ': Weapon 'prima di' dove AmmoType: Munizioni'. Aggiornerò la mia risposta per mostrarlo. Vorrei * fortemente * consigliare di utilizzare il prefisso 'T' per i parametri del tipo. –
Penso che sia meglio, ma posso chiederti perché hai detto che potrebbe non essere un modo utile di fare le cose? – vexe