Require override of method to call super

流过昼夜 提交于 2019-11-30 00:10:21

问题


I want that when a child class overrides a method in a parent class, the super.method() is called in that child 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?


回答1:


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.




回答2:


solution:

Look at the findBugs project ...

  • 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:


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
  }
}



回答4:


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:

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.

As noted elsewhere, there is by the way no way of requiring such a contract in java.




回答5:


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.




回答6:


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
    }
}


来源:https://stackoverflow.com/questions/6853638/require-override-of-method-to-call-super

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!