You know, I disagree vehemently with those who proclaim OO an abject failure. But I'm always a bit bemused with people who feel the need to build OO into everything, whether it needs it or not. The trick, of course, is to use it as it makes sense.
One of the problems with OO is that poorly designed programs can be much worse to grok the logic and flow of than poorly designed procedural programs, mostly because of how scattered the logic can be throughout an object hierarchy.
A much more modern* trend is to avoid deep class hierarchies whenever practical, preferring instead to try to use smaller, more reusable objects that are only responsible for a single task, and use composition of objects. This allows you to more easily test each individual component and assure correctness of behavior, and then build on that behavior. These days, a lot of my classes are very shallow, either a single class, or perhaps derived from an interface class to hide implementation details when necessary.
Class hierarchies still have their place on occasion. There are still cases when you must manage a number of types of related-but-different objects with a lot of common properties. But if you keep this paradigm to a minimum, you'll be a lot happier with OOP, and keep your code more manageable.
* If you consider the last 15 years or so "modern"