Two classes or interfaces with substantial shared structure — `Employee` and `Department` both carrying `name`, `id`, and similar id-management methods.
Two classes or interfaces with substantial shared structure (fields, methods); the agent verifying changes must update both consistently.
Two types with substantial shared structure get a common parent that owns the shared bits.
Shared structure lives on the parent with one declaration; queries about either subclass load the parent's contract once instead of paying the cost of loading N near-identical subclass declarations.
Before the refactoring
class Employee { name; id; salary; }class Department { name; id; budget; }
After the refactoring
class Party { name; id; }class Employee extends Party { salary; }class Department extends Party { budget; }
Bug fixes must land in both; future shared behavior has no obvious home; the relationship between the types is invisible to readers.
Bug fixes must land in both types; the agent's reasoning about shared invariants must verify they hold identically across both.
Inheritance is inflexible — if the duplication is shallow, prefer Extract Class (composition) over Extract Superclass.
Inheritance is inflexible; for shallow duplication, the agent's downstream changes are constrained by the parent in ways composition (Extract Class) would have avoided.
Bug fixes and new shared behavior land in one place; the relationship between the types is documented in code.
Shared behavior lives on the parent with one definition; edits to the shared method land once and propagate to every subclass through inheritance, removing the N-copy synchronization cost.
Extracting a superclass for shallow duplication — inheritance is inflexible, and the parent becomes a constraint on future divergence that composition (Extract Class) would have avoided.
Extracting superclasses for shallow duplication locks the agent into inheritance constraints when composition would have left both classes free to diverge.