我希望当子类重写父类中的方法时,在该子方法中调用super.method()
。
有没有办法在编译时检查这个?
如果没有,当发生这种情况时,我将如何抛出运行时异常?
答案 0 :(得分:40)
没有办法直接要求这个。但是,你可以做的是:
public class MySuperclass {
public final void myExposedInterface() {
//do the things you always want to have happen here
overridableInterface();
}
protected void overridableInterface() {
//superclass implemention does nothing
}
}
public class MySubclass extends MySuperclass {
@Override
protected void overridableInterface() {
System.out.println("Subclass-specific code goes here");
}
}
这提供了一个内部接口点,子类可以使用它来向公共myExposedInterface()
方法添加自定义行为,同时确保始终执行超类行为,无论子类做什么。
答案 1 :(得分:11)
查看findBugs项目......
示例......
import javax.annotation.OverridingMethodsMustInvokeSuper;
:
@OverridingMethodsMustInvokeSuper
protected String getLabel(){
...
}
覆盖:
@Override
protected String getLabel(){
// no call to Super Class!!
// gives a message
...
}
我已经使用它大约3年了。没有小猫受到伤害。
答案 2 :(得分:1)
遗憾的是,在编译时没有办法要求它,也没办法在运行时检测它(除非有一些特定于应用程序的逻辑或事件序列可用于检测未调用的方法)。最好的办法是大量记录方法。
如果你真的想要沿着这条道路前进,你可以使用类似这样的模式:
public class BaseClass {
public final void myMethod() {
// do special stuff here which must always happen ...
// allow subclasses to customize myMethod() here
myMethodCustom();
}
protected void myMethodCustom() {
// base class does nothing
}
}
答案 3 :(得分:1)
好吧,我可以假设超类方法中的初始化在别处使用。我会在超类方法中设置一个标志,并在以后需要初始化时检查它。更具体地说,让我们说setupPaint()是需要始终被调用的超类方法。那么我们就可以做到:
class C {
private boolean paintSetupDone = false;
void setupPaint() {
paintSetupDone = true;
...
}
void paint() { // requires that setupPaint() of C has been called
if (!paintSetupDone) throw RuntimeException("setup not done");
...
}
}
现在,如果C的子类没有调用setupPaint()函数,则无法设置(private)标志,并且需要对超类setupPaint()进行契约调用的方法,例如paint()将能够检查并抛出该异常。
如其他地方所述,顺便说一句,在java中无法要求这样的合同。
答案 4 :(得分:1)
在编译时无法检查这一点。 (但是,我听说过你可以在编译时使用注释来做这些建议,虽然我从未见过特定的注释解决方案,但我不知道它是如何完成的。)对于一种抛出异常的方法运行时间,请参阅this thread。也许您可以重构代码,以便基类具有final
方法,其中包含基本部分,并调用不需要super
调用的非最终方法。
答案 5 :(得分:1)
如果你自己打电话怎么样?而不是将实现指定为子类(您实际上不能做),只需使用基类的接口和实现来强制执行它。
public abstract class BaseClass {
public final void callMeFirst() {
// method that needs to be called before subclassing method runs
}
public final void makeSureWhateverGetsCalled() {
callMeFirst();
overrideMe();
}
public abstract void overrideMe();
}
public class OverridingClass extends BaseClass {
@Override
public void overrideMe() {
// do whatever needs to be done AFTER callMeFirst() is run
}
}
答案 6 :(得分:0)
对于在那里的 Android 开发人员,您只需使用@CallSuper批注即可。
示例:
public class BaseClass {
@CallSuper
public void myMethod() {
//do base required thing
}
}
在首要课程上:
public class OverridingClass extends BaseClass{
@Override
public void myMethod(){
super.myMethod(); //won't compile if super is not called
//do overring thing here
}
}
答案 7 :(得分:0)
AndroidX 解决方案:
要求 super
如果未在 @Override
方法中调用会引发编译错误:
import androidx.annotation.CallSuper;
class BaseClassThatRequiresSuper {
@CallSuper
public void requireSuper() {
}
}
class ChildClass extends BaseClassThatRequiresSuper {
@Override
public void requireSuper() {
super.requireSuper();
}
}
如果 ChildClass
没有调用 super.requireSuper()
,它会给你一个编译错误。说:
Overriding method should call super.requireSuper