Right now in some Java code I have something like this
class A {
void f() {
}
A() {
f();
}
}
class B extends A{
@Override
void f() {
//do some stuff
super.f();
}
}
class C extends B {
@Override
void f() {
//do some stuff
super.f();
}
}
I want to have f() called and then iterate upwards through each parent class, running the overridden f(). I do this by calling super.f() explicitly, although I'd like to not have to do this.
The reason why I do this is there post processing that must be done after the constructor in A is reached. And there is state in each class that much be properly init'd, which is why we have the upward trace of f()'s.
So the constructor of A is really
A() {
//init some state in a
f(); //run f(), which will depend on the previous operation
}
If I do something like new C(); I want C.f() called, then B.f() called, then A.f() called
Anyway, if there is a smarter way of doing this, I'm open to it.
Calling non-final methods in a constructor is generally a bad idea - at the very least, I'd suggest you document it heavily. Bear in mind that when f() is called, C's constructor won't have been called - and neither will any variable initializers. The object is only half-initialized, and so methods will need to be written very carefully.
There's no way of implicitly calling super.f() though in normal Java. Given the large warnings I'd be putting around that code, a single statement is far from the end of the world :)
If you want to verify that it's called, you could always check for the results of A.f() in A's constructor immediately after the call - that will check that the call has reached the top level.
This may help you somewhat - it's a way to enforce that the child class calls the super; this would help you detect developer mistakes where the implementer of a child class forgot to continue the call up the chain to super.f():
class A {
boolean fDone;
public final void f() {
fDone = false;
doF();
if (!fDone) {
throw new IllegalStateException("super.f() was not called");
}
}
protected void doF() {
//do some operation
fDone = true;
}
}
class B extends A {
protected void doF() {
//some operation, maybe repeat this pattern of using a flag to enforce super call
super.doF();
}
}
So, the child overrides doF(), but is required to call super.doF();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With