Don't call any overridable member methods in a constructor, especially if the class is likely to be extended or modified at a later stage.  Unless all constructors have been executed, including the subclass constructors, the object is not ready for use and should not be used.   It is possible that subclasses try to start using a half-constructed object via the this pointer passed into other methods, assuming it is a fully constructed object.  The super() constructor is always called first.  

eg.

public class Box
{
    public Box(int argWidth, int argDepth, int argLength)
    {
        width = argWidth;
        depth = argDepth;
        length = argLength;

        // Oops, a call to a method outside the constructor before
        // the instance has been created yet.
        displayName = getDisplayText();
    }
     
    public getDisplayText()
    {
        return “Box: “ + width + 'x' + depth + 'x' + length;
    }
}


public class BetterBox extends Box
{
    public BetterBox(int argWidth, int argDepth, int argLength,  
                     Color argColor)
    {
        // Oops! We have a BetterBox only half instantiated and hidden
        // away in our call to super(). getDisplayText() is going to be
        // called to return a description of what it thinks is a complete
        // Box, but color hasn't been defined yet (color is still null!)

        super(argWidth, argDepth, argLength);
        color = argColor;
    }

    // overridden method
    public getDisplayText()
    {
        return “Better Box: “ + width + 'x' + depth + 'x' + length  
             + “, ” + color;
    }
}

Exception: Sometimes it is useful to track a list of constructed objects by adding each new instance to a collection from within the constructor – the constructor is the most logical place to put such code, however the object will not be valid until sometime after storage, and worse, if the subclass constructor fails, an invalid object will be remembered.  However, the called method should be private, so it can't be ever be overridden.

public Box(int argWidth, int argDepth, int argLength)
{
    width = argWidth;
    depth = argDepth;
    length = argLength;
    rememberBoxInstance(this);
}
blog comments powered by Disqus