@VGR said:
Even single inheritance gets the crap abused out of it on a regular basis. There is no single antipattern more common in Java than the use of inheritance where it is not needed. I'm confident multiple inheritance, if available, would be beneficial in only a tiny fraction of cases where it would end up getting used.
I really don't buy this. MI doesn't get used in C++ that often. And most of the time it's used it's used reasonably. I know it's fashionable to rail against it, to mutter about the "dreaded diamond" and generally regard it as some kind of an evil, but *in practice* it isn't. *In practice* it's either not used (because it's unnecessary), it's used in a way that's harmless (that is not to say it's necessarily "good OO" but it's not actually cauusing any problem), or it's used reasonably. I read and write a large amount of C++, and if I were to pick a feature to remove because of "abuse", it certainly wouldn't be MI; it gets a lot of bad press, but it's just not deserved.
(FWIW the feature I would remove is broad syntactic compatibility with C; particularly egregious is the declarator mess, but there are other issues such as its inability to be parsed with any "simple" parser (due to typedefs and templates). These issues could be fixed, but the syntax would have to change. The upsides of this would be immense; much better tools (e.g. refactoring support) would be feasible, and it would I hope prevent people writing so-called "C/C++", that is, idiomatic C with enough C++ness to prevent use of a C compiler).
The trade-off isn't worth it, and I honestly think that trade-off was something the designers of Java considered.
I think more fundamentally the idea of designing a programming language for skills of the lowest common denominator is misguided. I don't believe it appreciably improves bad code, nor does it reduce the amount of bad code that exists (bad coders will abuse anything, no matter how constrained the language developers try to make them; preventing them from abusing feature X means only that they vent their incompetence on feature Y). I do, however, believes that it hurts *good* developers writing good code; they are forced to use inelegant hacks to work around language flaws.
If the bar at the bottom were raised as the bar at the top were lowered, one might claim that it was a trade-off worth making. I don't believe that has happened, though.
Consider another example; checked exceptions. This (misguided) feature was an attempt to force proper exception handling on people. It's been an abject failure. It leads to catch(Exception e) {}, and that ain't "exception handling". It's just bad, bad, bad. In actual fact, it makes bad code even worse. In general it is FAR better to let an exception you can't handle just bubble to the top of the stack (because it's better to do nothing than it is to do the wrong thing) and end the thread. Yet this *perfectly reasonable* practice is made almost impossible by checked exceptions because of an attempt to make bad coders write better code.