3

Imagine that I am writing a game where tanks fight with each other.

A generic Tank class is created and has the method fire() which fires a cannon, looks like this Tank::fire() { /* fires a cannon */ }

And then there is a class for BossTank which fire() fires a cannon and also a missile.


A senior advised me to do something like:

Tank::fire() { fireProjectile(); }, and create a new function:

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

Then in BossTank we can do inherit:

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

I don't know why, I do not feel good about this. Maybe because the line parent::fire() looks inconsistent with more elementary lines for /* fire a missile */

Another coworker suggested this:

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

Then BossTank::fire() { fireCannon(); fireMissile(); } with BossTank::fireMissile { /* fire a missile */ } (this is a method only in this class)


I would like to go along these lines:

Tank::fire() { fireCannon(); fireAdditionalProjectiles(); } with Tank::fireAdditionalProjectiles() empty.

Then in BossTank we can override fireAdditionalProjectiles() to fire missiles.


So here are 3 ways to implement the "same" thing:

  1. Senior: Inheritance - extracting fire cannon so no duplication.
  2. Coworker: Override fire() and implement a new function only in BossTank
  3. Me: Implement new function fireCannon() for no duplication, and fireAdditionalProjectiles() for overriding in BossTank

Is this a personal preference or there are standards regarding this situation?

Sunny Pun
  • 139

1 Answers1

8

If you have a variety of tanks with different weapons, then it makes sense of compose your tank class

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

If all Tanks always have a Cannon, which always fires then overriding the Fire method and then calling the base class Fire plus some extras makes sense.

But I believe the current trend is towards composition, as people find that with multiple layers of inheritance the logic becomes too hard to follow.

For example, if you have a SuperBossTank which fires two missiles but no cannon you would have to introduce a new BaseTank with no weapon

Ewan
  • 83,178