Deep inheritance chains are brittle. When requirements change, you end up fighting the hierarchy.
// dirty — inheritance chain
class Animal {
constructor(public name: string) {}
}
class Dog extends Animal {
bark(): string { return this.name + ' says: woof'; }
}
class Cat extends Animal {
meow(): string { return this.name + ' says: meow'; }
}Refactor using composition: create createAnimal(name, sound) that returns an object with a speak() method. No classes, no inheritance.solve(name, sound) calls createAnimal(name, sound).speak().
solve('Rex', 'woof') → 'Rex says: woof'
Sample tests