The same problem, four different solutions
Flight has evolved on Earth at least four separate times: in insects, pterosaurs (extinct flying reptiles), birds, and bats. Each lineage solved the problem independently — none inherited flight from the others. Birds didn't get wings from pterosaurs; bats didn't get wings from birds.
Each one ended up with a different implementation, all under the same interface (fly()):
- Insects. Wings made of chitin (the same stuff as their exoskeleton). No bones inside. Powered by indirect muscle attachments that distort the thorax.
- Pterosaurs. A skin membrane stretched over a hugely elongated fourth finger. Hollow bones, huge wing.
- Birds. Feathers attached to a modified arm. The arm bones are short, the feathers do most of the lift.
- Bats. A skin membrane stretched between elongated fingers (different fingers from pterosaurs). Modern lineage; they're mammals, not reptiles.
This is polymorphism — same interface, different implementations. Biologists call it *convergent evolution*. Different lineages, different inheritance chains, the same problem-shape, similar enough solutions that the interface is unmistakable.
Convergent evolution is everywhere once you look
- Eyes. Vertebrate eye (back-to-front retina), octopus eye (front-to-back retina), insect compound eye, mantis shrimp eye. Different implementations of the
see()interface, evolved independently. - Echolocation. Bats and dolphins both navigate by sonar. Mammals, but separated by 60+ million years of independent evolution. Same interface, two different code bases.
- Streamlined body. Tuna (fish), dolphin (mammal), ichthyosaur (extinct reptile). Same body shape (hydrodynamic interface), three different ancestries.
- Eusociality. Bees, ants, termites, naked mole rats. Different lineages independently discovered the same colony architecture.
What this means for the OO view
If polymorphism keeps showing up across unrelated lineages, the problem shapes are real and the interfaces are determined by the problem, not by the lineage. Flight has a shape — generate lift, control direction, manage drag — and any lineage that solves it ends up implementing roughly the same interface, regardless of what code it inherited.
This is the same observation that programmers eventually make: certain interfaces are not arbitrary. They're shaped by the problem. The right interface for sorting is roughly the same in any language that ever existed; the right interface for flight is roughly the same across insects, birds, and bats. Nature and code agree on what good interfaces look like, because they're shaped by the problem, not the implementer.