9

Often in my designs I define an abstract superclass whose subclasses will vary mostly in their values for the fields defined in the superclass.

For example, in a game I'm developing there's an abstract class Missile with a number of subclasses. Each one defines a different value for member variables such as MAX_SPEED, MASS, FLYING_FORCE, which are then used in calculations performed in the superclass.

I use abstract methods in Missile to force it's subclasses to define these variables. For example I simply have an abstract method defineMass() that forces subclasses to define their own value of mass.

A different example would be my Entity class (the superclass of all game-play classes) defining an abstract loadImage() method that forces subclasses to define an image for themselves.

Is this good practice? Is it common?

1
  • 1
    Every thing depends on your requirements.. I mean how much you understand the application. Unless you face an issue or some part is very difficult handle, your design fine and perfect.
    – sush
    Commented Jun 29, 2014 at 12:00

4 Answers 4

4

I think inheritance deserves better purposes:

  • If the only thing varying between subclases, and between subclasses and its superclass are the values of some members, then you are abusing inheritance or using it wrong. You could use builder pattern to create missiles with different values. If builder pattern is too complex for the task, factory methods like buildMissileOfTypeA() and buildSuperMassiveMissile() would do.
  • You would be putting inheritance to good use if the abstract methods were related to behaviors that the subclasses would implement in potentially different ways, but not just to set a value of a member.
  • Besides, you are not really forcing subclasses to define their own value, they just can simply implement an empty method that doesn't change the value of the mass and the compiler will be happy with it.
4
  • 2
    While I agree with 1 and 2, 3 is not true; the OP could define protected abstract float getMass(); and that would force the subclass to provide a value.
    – SJuan76
    Commented Jun 29, 2014 at 9:52
  • @SJuan76 OP mentions only defineMass. Commented Jun 29, 2014 at 14:21
  • Thanks for your answer. What you wrote made me think, and I tried to employ the Builder pattern instead of having a different subclass for every Missile type. However I ended up with more complexity than I would have with simple inheritance. I needed a different ConcreteBuilder for every kind of missile, and the differences between them were things like more mass here and less speed there. So I'm not sure what this gives me. Might as well have different Missile subclasses with these differences. Do I not understand the pattern correctly?
    – Aviv Cohn
    Commented Jun 29, 2014 at 15:59
  • @Prog You are right, builder pattern maybe be too complex for this. I changed my answer to add a recommendation for factory methods. Commented Jun 29, 2014 at 16:51
4

I would place these fields in the constructor, e.g

public abstract class Missile
{
    int MAX_SPEED, MASS, FLYING_FORCE

    Missile(int maxSpeed, int mass, int flyingForce)
    {
        MAX_SPEED = maxSpeed;
        MASS = MASS;
        FLYING_FORCE = flyingForce;
    }
}

And then create the child classes as follows e.g.

public class Rocket extends Missile
{
     Rocket()
     {
         super(100, 20, 50);
     }
}

So the fields must be stated whenever the Missile class is called, but can be really tidily hard wired into its child classes.

3

If you want to force a subclass to set the right member field, you might specify a constructor with all the needed parameters in the superclass and thus forcing the subclasses to call the constructor (provided that your language of choice forces you to call super constructors).

0

It's a pattern I've seen and used often, and I see it as a form of the Template Method pattern.

Consider a BasePlugin class, for instance, that defines an abstract Name and SupportedTypes properties. These properties are used as part of the base class shared implementations - using the Name for logging, maybe, or using SupportedTypes for validation. This might be in addition to the overridden logic of ExecutePlugin or whatever.

One change I would make from your design is to define a getMass method (or, if in C# or a similar language, a property with a getter) rather than your defineMass. getMass's name implies that its usage is as a getter, used anywhere in the base class code where the value is neede. defineMass implies that it will be called in the constructor, and it will, itself, store a value in a field in the base class. That seems unnecessary, and makes defineMass either have side effects (possibly affecting multithreaded code) or, alternately, just not being a very descriptive name, assuming you did intend for it to be a getter.

Rather than "force the derived class to define the values", which is just a roundabout way of saying "I need the derived class's values", simply ask the derived class for the value and let it do whatever it needs to give it to you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.