Per ereditare o sovrascrivere?

3

Immagina di scrivere un gioco in cui i carri armati combattono tra loro.

Una classe generica Tank è creata e ha il metodo fire () che lancia un cannone, assomiglia a questo Tank::fire() { /* fires a cannon */ }

E poi c'è una classe per BossTank che fire () lancia un cannone e anche un missile.

Un anziano mi ha consigliato di fare qualcosa del tipo:

Tank::fire() { fireProjectile(); } e crea una nuova funzione:

Tank::fireProjectile() { /* fire a cannon */ }

Quindi in BossTank possiamo ereditare:

BossTank::fireProjectile() {
  parent::fireProjectile();
  /* fire a missile */
}

Non so perché, non mi sento bene per questo. Forse perché la riga parent::fire() sembra incoerente con più linee elementari per /* fire a missile */

Un altro collega ha suggerito questo:

Tank::fire() { fireCannon(); } e Tank::fireCannon() { /* fire a cannon */ }

Quindi BossTank::fire() { fireCannon(); fireMissile(); } con BossTank::fireMissile { /* fire a missile */ } (questo è un metodo solo in questa classe)

Mi piacerebbe seguire queste linee:

Tank::fire() { fireCannon(); fireAdditionalProjectiles(); } con Tank::fireAdditionalProjectiles() vuoto.

Quindi in BossTank possiamo sovrascrivere fireAdditionalProjectiles() per lanciare i missili.

Quindi ecco 3 modi per implementare la "stessa" cosa:

  1. Senior: Ereditarietà - estraendo cannoni antincendio quindi nessuna duplicazione.
  2. Collaboratore: Sostituisci fire() e implementa una nuova funzione solo in BossTank
  3. Me: implementa la nuova funzione fireCannon() per nessuna duplicazione e fireAdditionalProjectiles() per l'override in BossTank

Questa è una preferenza personale o ci sono degli standard riguardo a questa situazione?

    
posta Sunny Pun 21.10.2017 - 19:21
fonte

1 risposta

8

Se hai una varietà di carri armati con armi diverse, allora ha senso comporre la tua classe di carri armati

class Tank
{
    List<Weapon> weapons;
    void Fire()
    {
        foreach(var w in weapons) {w.Fire();}
    }
}

Se tutti i Carri armati hanno sempre un Cannone, che spara sempre e quindi sovrascrive il metodo Fuoco e poi chiama la classe base Fuoco più alcuni extra ha senso.

Ma credo che la tendenza attuale sia verso la composizione, poiché le persone scoprono che con più livelli di ereditarietà la logica diventa troppo difficile da seguire.

Ad esempio, se hai un SuperBossTank che lancia due missili ma nessun cannone dovrai introdurre un nuovo BaseTank senza armi

    
risposta data 21.10.2017 - 19:50
fonte

Leggi altre domande sui tag