The point is that while subclassing makes it easy to re-use code in multiple places, but it isn’t very modular. One of my first jobs involved moving one class from a branch in a convoluted inheritance tree to another branch. This meant changing some of the superclasses and – you guess it – it exploded in all the wrong places. Speak about pain.
The problem with subclassing is that each subclass depends on all its superclasses. You can’t take the code out and re-use it elsewhere, especially since most sane languages don’t allow true multiple inheritance. The larger your subclass tree grows, the bigger the dependencies grow and the less flexible it gets. Stuff from the lower rungs of the hierarchy cannot be re-used in any useful way, and the whole hierarchy may not fit easily into other projects either.
So, if you want to be extra nice to your fellow developers, including your future self, try building your application out of simple, independent blocks. The architecture astronauts have made up lots of names for that, but the concept is actually refreshingly simple.
What you can do depends on which environment you’re in: In Java (and Java-like languages, say, C#) you can make small components and tie them together using Interfaces, which describe how you can interact with an object. Which allows you to replace one component for another that uses the same interface.
In Ruby, you don’t need the interfaces since the communication between objects is pretty much free-form already. However, you get a nifty feature called “Mixin“, which allows you to write some methods in one place and then re-use same code in different places.
In any case, watch out that you keep things simple, stupid. And remember that sometimes plain old inheritance may be the simplest thing.