Call Super
Call Super requires overrides to invoke the parent method, an unenforceable contract that breaks silently when forgotten. Restructure with the template method and non-virtual interface idioms so the base controls invocation and subclasses fill safe hooks.
Call Super is an anti-pattern in which a base class requires that any override of one of its methods must call the parent's version (super.method()) for the object to work correctly. The contract lives only in documentation or convention: forget the super call, and the object silently misbehaves.
Why It Happens
Framework and library authors use inheritance hooks to let users customize behavior, but they also need their own setup or teardown to run. Rather than separating the fixed part from the customizable part, they fold both into one overridable method and instruct subclasses to call super. This is common in lifecycle methods (initialization, event handlers, onCreate, dispose) across UI and component frameworks.
Why It Hurts
The requirement is unenforceable by the compiler, so it is easy to forget, and the failure is silent — no error, just missing behavior or a leaked resource. The order of the super call may matter (before or after the subclass's work), adding another invisible rule. Deep hierarchies compound the fragility, since every level must remember to chain. The result is a contract that depends on every future author reading and obeying prose, which they inevitably will not.
Warning Signs
- Documentation that says 'subclasses must call super.'
- Objects that break subtly when an override omits the super call.
- Rules about whether super must be called first or last.
- Lifecycle methods that mix framework bookkeeping with user hooks.
Better Alternatives
Use the Template Method Pattern correctly: make the entry point a non-overridable method that performs the required steps and calls a separate, designated hook method for the subclass to fill in. This is the non-virtual interface idiom — the base controls the skeleton and invocation order, while subclasses override only the safe extension points, so there is nothing to forget. Prefer composition over inheritance by accepting a callback or strategy instead of requiring a subclass at all.
How to Refactor Out of It
Split each call-super method into two: a final/sealed public method that runs the mandatory base logic and then invokes an empty protected hook, and the hook itself, which subclasses override without any obligation to call super. Migrate existing subclasses to override the hook. Where customization does not need inheritance, replace it with an injected function or strategy object. Verify with tests that base behavior runs regardless of what the subclass does, and that omitting customization is harmless.