Two or more subclasses implement the same method identically — `Manager.name()` and `Engineer.name()` both return `this._name` with no variation.
Two or more subclasses implement the same method identically; the agent verifying behavior must check every subclass and confirm they actually agree.
Methods that subclasses implement identically move to the shared superclass.
The method lives on the parent with one implementation; queries about behavior across subclasses load one method body instead of paying the token cost of loading N near-identical bodies.
Before the refactoring
class Manager extends Employee { name() { return this._name; } }class Engineer extends Employee { name() { return this._name; } }
After the refactoring
class Employee { name() { return this._name; } }class Manager extends Employee {}class Engineer extends Employee {}
Bug fixes must land in every copy; the shared behavior isn't expressed in the hierarchy; new subclasses copy the same boilerplate.
Bug fixes must land in every copy; the agent verifying consistency must update every subclass and risk drift.
If the methods only superficially resemble each other, pulling up creates a fake-shared abstraction — unify only when behavior is actually identical.
If the methods only superficially resemble each other (same name, different semantics), pulling up creates a fake-shared abstraction the agent must constantly disambiguate.
One implementation, one place to fix; subclasses focus on what's actually different.
Edits to the shared behavior land in one parent method; the agent does not load N subclass bodies to verify they still agree, and generated code that calls the method from any subclass dispatches to the same implementation.
Pulling up methods that only superficially resemble each other — the parent gets a method whose subclasses each interpret differently, creating a fake-shared abstraction.
Pulling up methods that share a name but not behavior produces one parent method the agent reads as canonical; generated code that calls the method from any subclass runs the parent's behavior, dropping the subclass-specific work the original separate methods performed.