In .NET, one can specify a \"mustoverride\" attribute to a method in a particular superclass to ensure that subclasses override that particular method. I was wondering whether
I'm not sure which attribute you're thinking about in .NET.
In VB you can apply the MustOverride
modifier to a method, but that's just the equivalent to making the method abstract in Java. You don't need an attribute/annotation, as the concept is built into the languages. It's more than just applying metadata - there's also the crucial difference that an abstract method doesn't include any implementation itself.
If you do think there's such an attribute, please could you say which one you mean?
I don't quite see why you would not want to use abstract modifier -- this is intended for forcing implementation by sub-class, and only need to be used for some methods, not all. Or maybe you are thinking of C++ style "pure abstract" classes?
But one other thing that many Java developers are not aware of is that it is also possible to override non-abstract methods and declare them abstract; like:
public abstract String toString(); // force re-definition
so that even though java.lang.Object
already defines an implementation, you can force sub-classes to define it again.
Ignoring abstract methods, there is no such facility in Java. Perhaps its possible to create a compile-time annotation to force that behaviour (and I'm not convinced it is) but that's it.
The real kicker is "override a method in a superclass that itself has some logic that must be run through". If you override a method, the superclass's method won't be called unless you explicitly call it.
In these sort of situations I've tended to do something like:
abstract public class Worker implements Runnable {
@Override
public final void run() {
beforeWork();
doWork();
afterWork();
}
protected void beforeWork() { }
protected void afterWork() { }
abstract protected void doWork();
}
to force a particular logic structure over an interface's method. You could use this, for example, to count invocations without having to worry about whether the user calls super.run()
, etc.
Android has a new annotation out as announced in the Google I/O 2015: @callSuper
More details here: http://tools.android.com/tech-docs/support-annotations
I've been thinking about this.
While I don't know of any way to require it with a compile error, you might try writing a custom PMD rule to raise a red-flag if your forgot to override.
There are already loads of PMD rules that do things like reminding you to implement HhashCode if you choose to override equals. Perhaps something could be done like that.
I've never done this before, so I'm not the one to write a tutorial, but a good place to start would be this link http://techtraits.com/programming/2011/11/05/custom-pmd-rules-using-xpath/ In this example, he basically creates a little warning if you decide to use a wildcard in an import package. Use it as a starting point to explore how PMD can analyze your source code, visit each member of a hierarchy, and identify where you forgot to implement a specific method.
Annotations are also a possibility, but you'd have to figure out your own way to implement the navigation through the class path. I believe PMD already handles this. Additionally, PMD has some really good integration with IDEs. https://pmd.github.io/
If you need some default behaviour, but for some reason it should not be used by specializations, like a implementation of a logic in a non abstract Adapter class just for easy of prototyping but which should not be used in production for instance, you could encapsulate that logic and log a warning that it is being used, without actually having to run it.
The base class constructor could check if the variable holding the logic points to the default one. (writing in very abstract terms as I think it should work on any language)
It would be something like this (uncompiled, untested and incomplete) Java (up to 7) example:
public interface SomeLogic {
void execute();
}
public class BaseClass {
//...private stuff and the logging framework of your preference...
private static final SomeLogic MUST_OVERRIDE = new SomeLogic() {
public void execute() {
//do some default naive stuff
}
};
protected SomeLogic getLogic() { return MUST_OVERRIDE; }
//the method that probably would be marked as MustOverride if the option existed in the language, maybe with another name as this exists in VB but with the same objective as the abstract keyword in Java
public void executeLogic() {
getLogic().execute();
}
public BaseClass() {
if (getLogic() == MUST_OVERRIDE) {
log.warn("Using default logic for the important SomeLogic.execute method, but it is not intended for production. Please override the getLogic to return a proper implementation ASAP");
}
}
}
public GoodSpecialization extends BaseClass {
public SomeLogic getLogic() {
//returns a proper implementation to do whatever was specified for the execute method
}
//do some other specialized stuff...
}
public BadSpecialization extends BaseClass {
//do lots of specialized stuff but doesn't override getLogic...
}
Some things could be different depending on the requirements, and clearly simpler, especially for languages with lambda expressions, but the basic idea would be the same.
Without the thing built in, there is always some way to emulate it, in this example you would get a runtime warning in a log file with a home-made-pattern-like-solution, that only your needs should point if it is enough or a more hardcore bytecode manipulation, ide plugin development or whatever wizardry is needed.