[英]Java, Call overridden method implicitly
Right now in some Java code I have something like this 现在在一些Java代码中,我有类似的东西
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()
. 我希望调用f()
然后向上遍历每个父类,运行重写的f()
。 I do this by calling super.f()
explicitly, although I'd like to not have to do this. 我通过显式调用super.f()
来做到这一点,尽管我不想这样做。
The reason why I do this is there post processing that must be done after the constructor in A is reached. 我这样做的原因是必须在到达A中的构造函数之后进行后处理。 And there is state in each class that much be properly init'd, which is why we have the upward trace of f()
's. 并且每个类中都有状态正确初始化,这就是为什么我们有f()
的向上轨迹。
So the constructor of A
is really 所以A
的构造函数确实如此
A() {
//init some state in a
f(); //run f(), which will depend on the previous operation
}
If I do something like new C();
如果我做new C();
I want Cf()
called, then Bf()
called, then Af()
called 我想要调用Cf()
,然后调用Bf()
,然后调用Af()
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 . 在构造函数中调用非final方法通常是一个坏主意 - 至少,我建议你大量记录它。 Bear in mind that when f() is called, C's constructor won't have been called - and neither will any variable initializers. 请记住,当调用f()时,不会调用C的构造函数 - 也不会调用任何变量初始值设定项。 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. 虽然在普通的Java中没有办法隐式调用super.f()
。 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 Af()
in A's constructor immediately after the call - that will check that the call has reached the top level. 如果你想验证它是否被调用,你可以在调用后立即检查A的构造函数中的Af()
结果 - 这将检查调用是否已达到顶级。
This may help you somewhat - it's a way to enforce that the child class calls the super; 这可能对你有所帮助 - 这是一种强制子类调用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(): 这将帮助您检测开发人员错误,其中子类的实现者忘记继续调用链到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(); 所以,孩子会覆盖doF(),但是需要调用super.doF();
As far as I know, there's no way to do this. 据我所知,没有办法做到这一点。 AspectJ might do something similar to this, but then you'd have to tag it with an annotation, I suppose, which is hardly less work than just calling super.f()
. AspectJ可能会做类似的事情,但是我想你必须用注释来标记它,这比调用super.f()
少得多。 You need to signify that the superclass method is being called, because you need to have the ability to make that decision for each subclass separately - otherwise, you might have a subclass that doesn't want to delegate anything to the superclass at all - so the default is that you just put in the code. 您需要表示正在调用超类方法,因为您需要能够单独为每个子类做出决定 - 否则,您可能有一个子类根本不想将任何内容委托给超类 - 所以默认是您只需输入代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.