Refused Bequest
Subclasses that don’t want their inheritance.
“Subclasses get to inherit the methods and data of their parents. But what if they don’t want or need what they are given?” – Fowler & Beck
Signs of Use (Symptoms)
- Overriding a method to do nothing (
@Override void foo() {}). - Throwing
NotImplementedExceptionfor inherited methods. - Subclass ignores most of the parent’s interface.
Why it is bad (Consequences)
- LSP Violation: Subtype cannot substitute for parent.
- Confusion: API promises something the implementation doesn’t deliver.
Why it happens (Root Cause)
Inheritance was used for code reuse, not for “is-a” relationship.
When it might be okay (Exceptions)
- Very rarely. If you intentionally want to “disable” a feature for a subtype, document it heavily.
Explanation
Problem
Duck extends Bird. Bird.fly() exists. But Duck.fly() throws an error because Ducks don’t all fly (Rubber Duck!).
The Flaw
Inheritance was misused. RubberDuck is not a Bird.
Real world analogy
Inheriting a family business you don’t want to run. You ignore the company.
Refactoring Solution
- Replace Inheritance with Delegation: Use composition.
- Push Down Method: Remove unwanted methods from the parent into the specific subclass that needs them.
Pros and Cons (of the Antipattern)
| Pros (Why people do it) | Cons (The price you pay) |
|---|---|
Comparison
- Related Antipatterns: None directly.
- Related Principles: Violates LSP.
Code example
Typescript
Bad (The Antipattern)
Good (The Fix)
PHP
Good (The Fix)