Object-Orientation AbusersMedium

Refused Bequest: What It Costs and How to Fix It

A subclass that inherits methods and data it does not need or want, violating the Liskov Substitution Principle.

Annual Cost$2k - $16k
Severity
3/5
CategoryObject-Orientation Abusers
Detection4 tools

What It Is

Refused Bequest occurs when a subclass inherits from a parent but only uses a fraction of the inherited interface. The subclass may override methods to throw exceptions, leave inherited methods empty, or simply ignore large portions of the parent's API. This is a sign that the inheritance hierarchy is wrong: the subclass is not truly a specialisation of the parent. The Liskov Substitution Principle states that substituting a subclass for its parent should not break the program, but Refused Bequest violates this by making the subclass an unreliable stand-in.

Threshold: When a subclass overrides 3+ methods to do nothing or throw exceptions, the inheritance relationship is wrong. When a subclass uses less than half of the inherited interface, consider delegation.

Why It Costs Money

1

Developers who call parent-type methods on the subclass get surprising results (exceptions, no-ops, or wrong behaviour). These bugs are particularly expensive because they only manifest at runtime and often only in specific code paths.

2

The inheritance hierarchy becomes misleading documentation. New developers assume the subclass behaves like its parent, make changes based on that assumption, and introduce subtle bugs.

3

Refactoring the parent class is dangerous because changes may break subclasses in unexpected ways. Teams become afraid to improve the parent, leading to stagnation.

Specific Cost Mechanisms

  • Runtime surprises: methods that throw or silently fail when called on the subclass, costing 2-6 hours per incident
  • False assumptions: new developers misunderstand the hierarchy, introducing bugs that pass code review
  • Parent stagnation: fear of breaking subclasses prevents improving shared code

Estimated Annual Cost

Cost per instance by team size and codebase size. Based on $120,000 average developer salary. See full methodology.

Team SizeSmall (<50k LOC)Medium (50k-200k)Large (200k+)
3 devs$2,000$4,800$9,600
5 devs$3,300$8,000$16,000
10 devs$5,000$12,000$16,000
20 devs$6,600$16,000$16,000

How to Detect It

Specific rules and thresholds for automated detection. See full tool comparison.

SonarQube
squid:S1185 / squid:S1694

Overriding to do nothing, abstract class with no abstract methods

CodeClimate
method-count / file-lines

Indirect: subclass much smaller than parent suggests refused bequest

PMD
AbstractClassWithoutAbstractMethod

Parent with no abstract methods may indicate over-inheritance

IntelliJ IDEA
Refused bequest inspection

Directly detects unused inherited members

Refactoring Patterns

Proven techniques to eliminate this smell. See all refactoring patterns.

Replace Inheritance with Delegation

The subclass only needs a few methods from the parent

Effort: 2-6 hours
Impact: Eliminates false hierarchy and makes the real relationship explicit

Extract Superclass

Some siblings share behaviour but the current parent is too broad

Effort: 4-8 hours
Impact: Creates a correct hierarchy where inheritance is meaningful

Push Down Method/Field

Inherited members are only used by one subclass

Effort: 1-2 hours per member
Impact: Slims the parent and clarifies which class owns the behaviour

Related Smells