Creating a subclass in place of instantiating...

Started by
6 comments, last by jefferytitan 11 years, 11 months ago
I'm working on a game where I will manually construct a large number of Ship objects (100+), each with their own unique stats, but, of course, sharing the same properties and methods.

Someone suggested I should create a sub-class for each different ship to accomplish this, but this goes against my intuition. However, I don't know what would be bad about this approach either. This approach is tempting because I would be able to quickly access a particular subclass object with my IDE's auto-fill feature when I begin typing its name.

Is there a performance cost or disadvantage to creating sub-classes in this manner, where I could just create instances of the same class instead?
Advertisement
If the differences are small, then just a single Ship class with properties just as Speed, Firepower, etc would be fine. For the different types of ship you'd store a set of default attributes, for example an XML file containing the starting Speed, Firepower, Hitpoints, etc.

For bigger differences, if I recall correctly the tool to help you here is the Strategy Pattern:
http://en.wikipedia.org/wiki/Strategy_pattern

You have a general Ship class which has methods like Move, Attack, Defend, Retreat, etc, and then you can assign what those methods actually do at run-time. That means that different types of ship can use completely different code to perform each action. Once again you would store ship info in some way, e.g. an XML file, including the name of the method to use to Move, Attack, etc.
Thanks for the quick reply.

I'm sorry but I didn't fully understand your suggestions. It sounds like I shouldn't create sub-classes of the Ship class and instead store different ships' default values in an XML file, regardless of the class' complexity.

I'm curious, why do you recommend storing default values in an XML file? It seems more convenient to simply hard code the default values into the program.

And, is there anything bad about creating sub-classes in this case?
Creating subclasses won't have noticable performance issues (if any). For hundreds of ships, the main problem will be writing and maintaining all of that unnecessary code.

I would personally have a single class, and hardcode the different stats in a big array-of-structs for the first implementation and change it only if necessary. Doing the simplest thing that could possibly work is generally a good idea.
Someone suggested I should create a sub-class for each different ship to accomplish this, but this goes against my intuition. However, I don't know what would be bad about this approach either. This approach is tempting because I would be able to quickly access a particular subclass object with my IDE's auto-fill feature when I begin typing its name.

Is there a performance cost or disadvantage to creating sub-classes in this manner, where I could just create instances of the same class instead?
Both approaches have their own pros. In general, if the fields to be changed are just data, then it would be ideal to load them from a file and push them to a ctor.
As you noted, it is very handy to have a simplified subclass, just to build it with less ctor parameters, such as

class BaseShip {
...
public:
BaseShip(int param, string name, Behaviour attitude, Job task) { ... }
};
class MinerShip : public BaseShip {
public:
MinerShip() : BaseShip(0, "miner", b_peaceful, j_mine) { ... }
};

This benefit is short sighted. I'm not saying it's worth nothing, but you see already what's the best thing to do: load them up from a file.
You might consider JSON as well. I use jsoncpp.

However, there are issues. What to do if we need to actually provide more logic? In that case the options are

  1. Go for a subclass
  2. Turn code into data by using scripting

In general, rather than providing switches at a base class level, I strongly suggest to refactor in a more component-oriented approach, by breaking each ship in more basic components. Then a ship would be something like a collection of those components so instead of using the data directly, you would use it to instance objects to be used instead of the ifs involved in switching behaviour... I don't know if I'm able to convey the concept today.

Previously "Krohm"

Firstly, let's check we're on the same page. Do you mean that each Ship is unique, or are there types of Ships? My mental picture was for example, you have a small Fighter type, a large Dreadnought type, etc. The XML file (or whatever) would contain one set of stats for a Fighter, and one for a Dreadnought. You could then instantiate 30 Fighters and 5 Dreadnoughts based on those stats.

XML isn't required, it's just sometimes more convenient to be able to tweak the game without re-building it.

The disadvantage of subclassing too much is that you can add a cool feature to one subclass and then suddenly realise that you want the same feature in 4 more subclasses. You could copy and paste, which is bad for maintainability. Or you could do refactoring so they have a shared base class e.g. BigShip and LittleShip. But that can get complicated quickly, and often impossible in languages that lack multiple inheritance.

Plus sublclassing is fixed at compile time. With the approach that I'm suggesting, you could create a new ship type that uses bits and pieces of other ships' logic just by editing an XML file and providing new graphics. If you have an artist or level designer on your team who's not a coder, they likely won't want to edit code files and recompile to test their changes.
Thanks for the help everyone. I'm beginning to recognize the benefits to loading ships' data from a file. I admit I'm not used to working this way, but I realize storing/loading data from files an important skill to have, so it's about time I get used to it.

To answer your question, jefferytitan, all of the Ship types are the same. There won't be any differences in behavior, only properties (health, shields, etc.). The class (or classes) would be used to produce multiple instances each, as you described (e.g. 30 Fighters, 5 Dreadnoughts).

I will go with your suggestion and try using XML to supply my Ship objects with their default data.
Good luck. Do keep in mind that later in development you may want to move the data from a separate XML file to something harder to edit so players can't cheat at the game. As long as you have a relatively centralised place to read from the files it should be easy.

This topic is closed to new replies.

Advertisement