Holub recalls: "After the laughter died down, he explained that the real problem wasn't classes per se, but rather implementation inheritance: the extends relationship."
Inheritance violates encapsulation, undercutting the most basic of OOP principles.
Quite simply: Inheritance requires children to understand their parents (which I can tell you from personal experience is a dangerous assumption).
Subclassing leads to bloat (something Java needs more of...), because children inherit the methods of their entire ancestry chain. Which leads to things like JMenu having 433 methods.
It also locks new classes into preexisting concrete implementations, which introduces brittleness. A change in an ancestral method can break children unexpectedly. This is a well known drawback of inheritance.
Here is a verbatim quote from the Java API documentation for the Properties class:
This sort of thing has an odor about it. It reeks of poor design.
putAllmethods can be applied to a
Propertiesobject. Their use is strongly discouraged as they allow the caller to insert entries whose keys or values are not
setPropertymethod should be used instead. If the
savemethod is called on a “compromised”
Propertiesobject that contains a non-
Stringkey or value, the call will fail.
There's plenty more to be said on this subject, but it's been said elsewhere and I won't regurgitate needlessly. And again, I have to stress, I don't consider inheritance evil so much as misused. More on that some other time.
Gosling, Eich, Bloch, Holub, all know what they're talking about. Inheritance is overrated.