Of course, to clarify, it's not really possible to avoid in languages like Java, where it is more or less mandatory due to the design of its standard library (unless you avoid that too, which is a considerably worse idea), but you can still keep your own CODE clean with liberal use of `final` and interfaces.
Personally, I'm consistently baffled when programmers like yourself, who have come to appreciate that "inheritence [sic] is a very, very dangerous tool," continue to defend it so vigorously. If it offered really powerful or unique advantages, sure--but if you take a hard at what it actually provides, it's just syntactic sugar and a performance "optimization" (thin pointers) that's usually pessimal compared to other approaches. The downsides are significant and well-known (as mentioned above, Liskov substitution being undecidable is one consequence, but there are plenty of others). There's no point in making life harder for ourselves.