Java method extension instead of rewriting

Is there any type of @annotation or other method in Java to force an extension of a method instead of overriding?

To be specific, let's say I have a Foo class:

class Foo { public void bar(Thing thing) { // ... } } 

Is it possible at compile time to ensure that any X class that extends Foo and also overlaps the bar first calls super.bar(thing) ?

+4
source share
5 answers

No, you must write it explicitly.

Side note for constructors: A supercomputer null constructor will be implicitly called when an instance of the subclass is instantiated, however many parameters the last constructor has.

+3
source

Typically, you can create a final method that calls extensible.

 class Foo { @Override public final void bar(Thing thing) { // super code comes here this.doBar(thing); } public abstract void doBar(Thing thing); } 

When you call

 foo.bar(thing); 

your supercode is executed first, then the code from the child class.

This way you can protect your full bar logic and allow the extension or redefinition of only certain parts.

In addition, it allows you to perform a post-process of the result or break the code into specific subtasks.

+1
source

You can declare bar as final , and then call the abstract method from bar , which will force the subclasses to implement the "extension".

 abstract class Foo { public final void bar(Thing thing) { barImpl(thing); overrideMe(thing); } private final void barImpl(Thing thing) { // Original implementation of "bar" here. } protected abstract void overrideMe(Thing thing); } 

EDIT

I changed overrideMe from public to protected , so Foo users cannot just call overrideMe instead of bar .

+1
source

While you cannot force the code to call your superclass at compile time, it is not so difficult to detect at runtime when the code does not call the superclass.

 class Foo { private boolean baseCalled; public final void bar(Thing thing) { baseCalled = false; barImp(thing); if (!baseCalled) { throw new RuntimeException("super.barImp() not called"); } } protected void barImp(Thing thing) { baseCalled = true; . . . // base class implementation of bar } } 

Note that this continues to several levels of inheritance without further elaboration. This method works especially well for methods called from Foo ; in these cases, you can often refuse the qualifier and redirect final to the implementation method and simply define the base class method for setting the flag. Flag clearing will be performed at each call point.

The above template is widely used in the Android platform. This does not guarantee that super.barImp was named first in the override of the subclass; he has just been called.

0
source

You can try using the @AroundInvoke annotation if you use EJB.

Using reflection, you can find the same method in your parent class, and yo can call it with the same parameters as the original method called.

Note that in this case you should avoid calling super.bar(thing) , otherwise they will be called twice.

0
source

All Articles