Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: post-processing after subclass constructor completes

I want to define some common post-construction behavior for a group of classes. When you have shared behaviors in different classes, Java tells us to extract them out into a parent class.

Conceptually, it makes sense, we're saying, for objects of this type (and its subclasses), do some post-processing after it's constructed;

Practically, it's hard to do. You obviously can't put it in the parent class constructor because parent constructor is called before the subclass constructor. I could write a postInit() method in the parent class and require all subclasses to call it as their last statement in their constructors, but it doesn't seem very clean, as there's no way to enforce it, and people do forget.

Is there maybe some language construct that I'm not aware of that may solve my problem?

Thanks

Just a little more background on the requirement. Factory methods etc. that are suggested by many of the answers (which I've upvoted) below are all good ideas, but I don't really have that luxury. The actual situation is this, I have this parent class, which is extended by a couple of dozen subclasses, which are in turn used in many other places. So redesign how these subclasses are used is out of the question, and changing all subclasses is borderline possible. Ideally, I just need to change the parent class, so that's what I'm asking.

like image 363
RAY Avatar asked May 05 '11 03:05

RAY


People also ask

Can constructor be inherited through a subclass that call the superclass constructor?

Constructors are not inherited. The superclass constructor can be called from the first line of a subclass constructor by using the keyword super and passing appropriate parameters to set the private instance variables of the superclass.

Do subclasses inherit constructors?

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

What call must be made in the constructor of a subclass?

Invocation of a superclass constructor must be the first line in the subclass constructor.

Why super constructor is the first statement?

The Sun compiler says, call to super must be first statement in constructor . The Eclipse compiler says, Constructor call must be the first statement in a constructor . So, it is not stopping you from executing logic before the call to super() .


1 Answers

If you can't use a factory method for pragmatic reasons, the best solution I can think of is to create a protected final method in the root class that does the post processing, and add a call to the method to each and every leaf class; e.g.

public abstract class Root {
    ...
    protected final void finishInit() {
        // Do post-processing
    }
}

public abstract class Intermediate {
    ...
    protected Intermediate(...) {
        super(...);
        ...
        // don't call finishInit();
    }
    ...
}

public class Leaf {
    ...
    public Leaf(...) {
       super(...);
       ...
       finishInit();
    }
    ...
}

If Intermediate is not abstract then you need a separate public constructor to create instances that calls finishInit() at the end.


It's all a bit clumsy, but that's the penalty you have to pay if you can't/won't refactor your code to use factory methods.

like image 75
Stephen C Avatar answered Nov 09 '22 03:11

Stephen C