java 需要覆盖方法来调用 super
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6853638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Require override of method to call super
提问by Andrew Gaspar
I want that when a child class overrides a method in a parent class, the super.method()
is called in that child method.
我希望当子类覆盖父类中的方法时,super.method()
会在该子方法中调用。
Is there any way to check this at compile time?
If not, how would I go about throwing a runtime exception when this happens?
有没有办法在编译时检查这个?
如果没有,发生这种情况时我将如何抛出运行时异常?
回答by aroth
There's no way to require this directly. What you can do, however, is something like:
没有办法直接要求这个。但是,您可以做的是:
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");
}
}
This provides an internal interface-point that subclasses can use to add custom behavior to the public myExposedInterface()
method, while ensuring that the superclass behavior is always executed no matter what the subclass does.
这提供了一个内部接口点,子类可以使用它向公共myExposedInterface()
方法添加自定义行为,同时确保无论子类做什么,总是执行超类行为。
回答by will
solution:
解决方案:
Look at the findBugs project ...
看看 findBugs 项目...
- FindBugs
- Annotations package
- 查找错误
- 注解包
Example ...
例子 ...
import javax.annotation.OverridingMethodsMustInvokeSuper;
:
@OverridingMethodsMustInvokeSuper
protected String getLabel(){
...
}
Override:
覆盖:
@Override
protected String getLabel(){
// no call to Super Class!!
// gives a message
...
}
I've been using it for about 3 years. No kittens have been harmed.
我已经使用它大约 3 年了。没有小猫受到伤害。
回答by jtahlborn
unfortunately, there's no way to require it at compile time, and no way to detect it at runtime (unless there is some app specific logic or sequence of events that you could use to detect the method not being called). best thing to do is heavily document the method.
不幸的是,没有办法在编译时要求它,也没有办法在运行时检测到它(除非有一些特定于应用程序的逻辑或事件序列可以用来检测未被调用的方法)。最好的办法是大量记录该方法。
if you really, really want to go down this path, you could use something like this pattern:
如果你真的,真的想走这条路,你可以使用这样的模式:
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
}
}
回答by Sajid
Well, I can presume that the initialization in the superclass method is used elsewhere. I would set a flag in the superclass method and check it later when the initialization is needed. More specifically, let's say setupPaint() is superclass method that needs always to be called. so then we can do:
好吧,我可以假设超类方法中的初始化是在其他地方使用的。我会在超类方法中设置一个标志,稍后在需要初始化时检查它。更具体地说,假设 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");
...
}
}
Now if a subclass of C doesn't call the setupPaint() function, there's no way that the (private) flag will be set, and methods requiring the contractual call to the superclass setupPaint(), such as paint() will be able to check and throw that exception.
现在,如果 C 的子类不调用 setupPaint() 函数,则无法设置(私有)标志,并且需要对超类 setupPaint() 进行契约调用的方法,例如paint() 将能够检查并抛出该异常。
As noted elsewhere, there is by the way no way of requiring such a contract in java.
正如其他地方所指出的,顺便说一下,java 中没有办法要求这样的合同。
回答by Ted Hopp
There's not a way to check for this at compile time. (However, I've heard suggestions that you could do this at compile time with annotations, although I've never seen a specific annotation solution and I don't know how it would be done.) For a way to throw an exception at run time, see this thread. Perhaps you can refactor your code so that the base class has a final
method that includes the essential parts and calls a non-final method that does not require a super
call.
没有办法在编译时检查这一点。(但是,我听说您可以在编译时使用注释执行此操作的建议,尽管我从未见过特定的注释解决方案,而且我不知道如何完成。)对于在以下位置抛出异常的方法运行时,请参阅此线程。也许您可以重构您的代码,以便基类具有一个final
包含基本部分的方法并调用一个不需要调用的非 final 方法super
。
回答by Marvo
How about if you make the call yourself? Instead of dictating implementation to a subclass (which you really can't do) just enforce it with the interface and implementation of your baseclass.
如果你自己打电话呢?与其将实现指定给子类(您确实无法做到),只需使用基类的接口和实现来强制执行即可。
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
}
}