Java,隐式调用重写方法
现在在一些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(); } }
我希望调用f()
然后向上遍历每个父类,运行重写的f()
。 我通过显式调用super.f()
来做到这一点,尽管我不想这样做。
我这样做的原因是必须在到达A中的构造函数之后进行后处理。 并且每个类中都有正确初始化的状态,这就是为什么我们有f()
的向上轨迹。
所以A
的构造函数确实如此
A() { //init some state in a f(); //run f(), which will depend on the previous operation }
如果我做new C();
我想调用Cf()
,然后调用Bf()
,然后调用Af()
无论如何,如果有更聪明的方法,我会接受它。
在构造函数中调用非final方法通常是一个坏主意 – 至少,我建议你大量记录它。 请记住,当调用f()时,不会调用C的构造函数 – 也不会调用任何变量初始值设定项。 该对象只是半初始化,因此需要非常仔细地编写方法。
虽然在普通的Java中没有办法隐式调用super.f()
。 鉴于我将围绕该代码发出大量警告,单个声明远离世界末日:)
如果你想validation它是否被调用,你可以在调用后立即检查A的构造函数中的Af()
结果 – 这将检查调用是否已达到顶层。
这可能对你有所帮助 – 这是一种强制子类调用super的方法; 这将帮助您检测开发人员错误,其中子类的实现者忘记继续调用链到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(); } }
所以,孩子会覆盖doF(),但需要调用super.doF();
据我所知,没有办法做到这一点。 AspectJ可能会做类似的事情,但是我想你必须用注释标记它,这比调用super.f()
少得多。 您需要表示正在调用超类方法,因为您需要能够单独为每个子类做出决定 – 否则,您可能有一个不希望将任何内容委托给超类的子类 – 所以默认是您只需输入代码。