The documentation you linked to already explains the rationale behind the check. This can be useful in some situations. In practice, I've never turned it on, mostly because it is too cumbersome to administer, and you certainly don't want it for all your classes.
But you asked for a code example. Consider these two classes (YourSuperClass
is part of the API you provide, and TheirSubClass
is provided by the users of your API):
public abstract class YourSuperClass
{
public final void execute() {
doStuff();
hook();
doStuff();
}
private void doStuff() {
calculateStuff();
// do lots of stuff
}
protected abstract void hook();
protected final void calculateStuff() {
// perform your calculation of stuff
}
}
public class TheirSubClass extends YourSuperClass
{
protected void hook() {
// do whatever the hook needs to do as part of execute(), e.g.:
calculateStuff();
}
public static void main(final String[] args) {
TheirSubClass cmd = new TheirSubClass();
cmd.execute();
}
}
In this example, TheirSubClass
cannot change the way execute
works (do stuff, call hook, do stuff again). It also cannot change the calculateStuff()
method. Thus, YourSuperClass
is "designed for extension", because TheirSubClass
cannot break the way it operates (like it could, if, say, execute()
wasn't final
). The designer of YourSuperClass
remains in control, providing only specific hooks for subclasses to use. If the hook
is abstract
, TheirSubClass
is forced to provide an implementation. If it is simply an empty method, TheirSubClass
can choose to not use the hook.
Checkstyle's Check
is a real-life example of a class designed for extension. Ironically, it would still fail the check, because getAcceptableTokens()
is public
but not final
.