Personally, I think this is a large part of the problem with the whole "Is OO Good?" debate. OO was initially thought to be a solution to essentially simulations problems ("Simula"[1] - the first OO language - it was right in the name!), where Cat inheriting Animal makes sense.
It turns out this translates to general purpose programming exceedingly poorly. It spends your valuable class hierarchy budget on the wrong things, while discouraging spending it on the right things.
On the other hand, OO turned out to be a useful gateway into polymorphic programming (not the only one, but a useful one), and to be a useful organization principle in real programs when used differently. Instead of Cats inheriting from Animals, you have interfaces for things like Iterators, which aren't real world objects at all, and you have objects that encapsulate certain operations, or certain patterns, or other much more abstract things that have no concrete physical referent. This style can work fairly well, especially if you don't overuse inheritance.
The simulation argument has really faded in the past 20 years, but even now, you get some crossfire between people attacking that formulation vs. people defending the modern version, and they're talking about such different things they might as well not even be talking about the same paradigm.
And as is typically the case, education is a lagging indicator, and even fairly recently I've seen it training people on the simulation model, even though by the 2010s it was pretty clearly useless in practice.
well, if universities started by teaching something else that "Cat" inherits "Animal" in 2020 ...