Refused Bequest
Refused Bequest is a subclass that disables inherited members it does not want, breaking substitutability. Replace misused inheritance with composition and segregated interfaces, and reserve inheritance for genuine, Liskov-safe specialization.
Refused Bequest is when a subclass inherits methods or fields from its parent that it does not need, and 'refuses' the inheritance — overriding methods to do nothing, to throw UnsupportedOperationException, or simply leaving inherited behavior that makes no sense for the subtype. The class accepts the gift of inheritance but rejects most of it.
Why It Happens
Inheritance is often reached for as a code-reuse shortcut: a new class needs a few methods that an existing class has, so it extends that class to grab them. But 'has some useful methods' is not the same as 'is a kind of.' The subtype then carries members that belong to the parent's broader contract but not to the subtype, and the only way to cope is to disable them.
Why It Hurts
It usually violates the Liskov Substitution Principle: code written against the parent type breaks when handed the subclass, because the subclass does not honor the full contract (a method that throws instead of behaving). The hierarchy becomes fragile and misleading — the subclass's public API advertises operations it cannot perform. Readers cannot trust the type, and polymorphism becomes unsafe. The design says 'is-a' where reality is only 'reuses-some-of.'
Warning Signs
- Overrides that are empty or that throw 'not supported.'
- Inherited methods or fields the subclass never legitimately uses.
- A subclass that documents 'do not call method X on this type.'
- Casts and
instanceofchecks needed to use a hierarchy safely.
Better Alternatives
Prefer composition over inheritance: have the class hold the collaborator it needs and expose only the operations it actually supports. Apply the Interface Segregation Principle so types depend on small, focused interfaces rather than one fat base contract. Let the Liskov Substitution Principle be the test for any inheritance: a subtype must be usable anywhere its supertype is, with no surprises. Reserve inheritance for genuine, substitutable specialization.
How to Refactor Out of It
Identify subclasses that disable inherited members. If the relationship is really 'reuses code,' replace inheritance with composition: hold an instance of the former parent and delegate only the needed calls. If several subtypes need overlapping but not identical capabilities, split the fat base into smaller interfaces and have each type implement only what it supports. Re-check that every remaining subtype satisfies LSP. Update callers, remove the now-unnecessary overrides, and add tests asserting substitutability.