For the same reason you avoid inheritance in non-dynamic languages.
Inheritance is the strongest coupling relationship. Often times too strong, inflexibly so.
What you're expressing is that the child class must have an is-a relationship with the parent.
Otherwise it violates the Liskov Principle.
My incomplete but practical 2-liner is this:
The child should be perfectly substitutable with it's > parent, with no change in behaviour; meaning no errors and > no incorrect-behaviour in either.
This isn't an abstract rule, it has practical repercussions:
If Class A has an is-a relationship with Class B, you, or (most likely) another person that got convinced by your is-a assertion` of that relationship will be tempted to write something like this:
class Animal {
backLegs = new BackLegs()
move() {
this.backLegs.move()
}
}
// this is OK
class Dog extends Animal {
frontLegs = new FrontLegs()
move() {
super.move()
this.frontLegs.move()
}
}
// this is not OK
class Fish extends Animal {
frontLegs = null
fins = new Fins()
move() {
super.move()
this.moveFins()
}
}
// Now, you got a mixed array of items, some `animals`,
others are `plants`...
// we know all animals can move so:
items.
.filter(item => item instanceof Animal)
.forEach(animal => animal.move())
// Reference Error: cannot find frontLegs on Fish