There's a now well-known guideline that says "prefer composition over inheritance." When I saw that, it clarified a lot of things. While much of software design can theoretically be approached in terms of class hierarchies, that's rarely the right place to begin, since after you start preferring composition, inheritance is mostly just a tool to achieve polymorphism.
It's a bit of a tangent, but I think the "class Dog extends Animal" type of tutorial did a lot of damage to impressionable programmers. Because it's completely abstract and basically meaningless, it's impossible to look at it critically and discuss why you would choose this or another approach, so the idea of class hierarchies just becomes a sort of dogma (so to speak).
Just like "goto" in the days of old, it is best used sparingly.
It's a bit of a tangent, but I think the "class Dog extends Animal" type of tutorial did a lot of damage to impressionable programmers. Because it's completely abstract and basically meaningless, it's impossible to look at it critically and discuss why you would choose this or another approach, so the idea of class hierarchies just becomes a sort of dogma (so to speak).
As they say, "Those who can do. Those who can't teach".