It was about 12 years ago when I helped to write an application that featured a class hierarchy like the following:
I remember the code because I was the one to refactor the application to build the class hierarchy in an attempt to remove duplicated code.
I believed what I was creating was a better application.
What I actually created was a model where other developers struggled to understand when a virtual method override would kick in. They had to work hard to figure out when to properly call a base class method. All changes inside the hierarchy were like moving balanced blocks of wood in a game of Jenga. Someone eventually has to lose a game of Jenga. You just hope the structure stays stable enough to make it through through your turn.
As a kid my parents told me not to play with matches, not to go near the dog chained to the oak tree down the street, and to always hold on to the handrail when the back porch steps were wet.
As a kid, I didn't understand why my parents told me these things until I was burned, or chewed, or contemplating life during a cartwheeling descent of rain slickened steps.
Similarly, I believe there are some aspects of software development that you have to experience to truly appreciate. I've been looking for a good example where composition clearly trumps inheritance, and might have something that is contrived, of course, but reasonable enough to demonstrate the principle and demonstrate some of the pain.
Coming up next – the Composition Kata.