8

I have an abstract class Entity. Every class extending Entity will need some default and some customizable setup:

public abstract class Entity {

    protected Entity() {
        // ... default setup
        customSetup();
    }

    protected abstract void customSetup();
    // ...
}

My extending class MyEntity takes a parameter in the constructor, that will be used in customSetup():

public class MyEntity extends Entity {

    private Data data;

    public MyEntity(Data d) {
        super(); // in here customSetup() is called!
        data = d;
    }

    @Override
    protected void customSetup() {
        codeDependingOn(data); // will throw NPE: data==null yet!
    }
}

As comments state, this code won't work.

I could just throw away customSetup() and put all the custom code after super(), but having that abstract method makes clearer what you're supposed to put there.

I feel like I'm violating some rule of OOP design. What's the correct way to do what I want?

bigstones
  • 15,087
  • 7
  • 65
  • 82
  • 1
    Some / many people make the case that you should not call any non-final method from a constructor for the very reason Malcolm stated. – John B Oct 20 '11 at 17:43
  • Is customSetup() ever going to be called after the object is constructed? Why not just add the codeDependingOn(data) to your constructor? – AndrewC Oct 20 '11 at 17:48
  • possible duplicate of [What's wrong with overridable method calls in constructors?](http://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors) – DwB Oct 20 '11 at 17:50
  • 1
    @AndrewC: no, that's why I put it in the constructor. I just wanted to "encapsulate" the custom part of the setup. Thank you all for the help, I didn't know about that rule, but I've learned it the right way :) – bigstones Oct 20 '11 at 17:51

1 Answers1

9

This is generally a bad idea to call methods which can be overriden from a constructor. The problem is that the class is not yet fully initialized, and when the method is called in a subclass, it may cause trouble.

Take a look at this question: What's wrong with overridable method calls in constructors?, it has a good explanation.

Community
  • 1
  • 1
Malcolm
  • 41,014
  • 11
  • 68
  • 91
  • that's just what happened. so, should I just rethink the whole design? – bigstones Oct 20 '11 at 17:44
  • `customSetup()` must definitely be called after all the superclass and the current class constructors have run. Constructors don't work with overridable methods well, this is the part you should rethink. – Malcolm Oct 20 '11 at 17:48