OOP Part 2: Inheritance

Last time, we talked about two different approaches to designing objects for a game or application: Inheritance and Composition. It’s time to look at the pros and cons in more detail. Let’s start with inheritance.

Inheritance

When learning OOP, inheritance is what you learn! Create a common, generic ancestor-type class, and create new classes for specific game objects which inherit from, override and extend the functions of the ancestor. Repeat as desired. Let’s look at the consequences of following this model:

Pros:

  1. It’s easy to locate all functionality belonging to each type: they’re together in the source for the child class.
  2. It’s easy to write an appropriate constructor for the type; so you know the classes internal state will be consistent.
  3. It’s easy to guard against the wrong type being passed to a function at compile time: If you have Function AttackMonster(WithWeapon: TWeapon); the compiler will prevent you passing a TItem that isn’t a TWeapon.
  4. You can specify abstract methods in the parent where you know the divergent behaviour will be, and the language and compiler will help you get there and warn you if you’ve left something out.

Cons:

  1. You end up with *lots* of different classes – which may be in lots of different files.
  2. Some of the classes can be really, really small… e.g., a single method override.
  3. When looking at the child class implementation with a call to the inherited parent, you don’t know exactly what the parent does.
  4. If two different children of a common ancestor need the same functionality, you have to code it twice.
  5. Code that constructs instances must take care to call the correct constructor.
  6. You can’t “switch” a child to a different type; you need to destruct it and create a new instance of the other type.
  7. Greater risk of circular-references if your child classes need to interact with each other.

You can see the pattern forming. The Pros of this model tend to be that things are easier to setup up-front, when you’re initially coding the classes. The Cons tend to hit you later: when you’re extending functionality, or just coming back to the code after time spent elsewhere.

It’s also possible with this model to really make life impossible for yourself. If you come up against Con #4 and are tempted to move some of that common functionality in the parent class, congratulations: you just blasted Pro #1 and debugging and maintaining this code just became a nightmare, and now the parent needs to duplicate some child state in order to know which of these “optional-children” operations it should perform. Ick!

Note that this inheritance style is still arguably a gigantic code-safety and readibility improvement from old-style procedual code. The question is, can we do better? In Part 3, we’ll look at the alternative model of Composited classes.

Leave a Reply

Your email address will not be published. Required fields are marked *