Aggregation vs Inheritance

Anyone remember the war between Microsoft and IBM over aggregation versus inheritance?

It was basically the COM vs CORBA war. The Workplace Shell in OS/2 was based on inheritance - if you wanted to extend the shell, you subclassed one of the shell objects and overrode functions. Explorer, in Windows, being based on COM, went the other way - aggregation. The shell defined interfaces, and you implemented those interfaces.

A quote from the IBM side:

"Inheritance is dangerous, so Microsoft's COM won't support it.
It's like saying divide-by-zero is dangerous, so let's remove
the divide operation from our microprocessors."
-- Cliff Reeves, IBM Director of Objects

I wonder if IBM still has a Director of Objects. Anyway, I was reading Effective Java on Safari and I ran across this statement:

The main disadvantage of static factory methods is that classes without public or protected constructors cannot be subclassed. The same is true for nonpublic classes returned by public static factories. For example, it is impossible to subclass any of the convenience implementation classes in the Collections Framework. Arguably this can be a blessing in disguise, as it encourages programmers to use composition instead of inheritance

For some reason I guess I assumed Java would have gone the IBM way (which seemed to be the anti-Microsoft way, and Sun is all about choosing the anti-Microsoft way whenever they can) but fortunately it seems everyone agreed that COM's model of aggregation (composition) works better in the real world, and that adding functionality by subclassing and multiple inheritance wasn't the way to build a system. Cool.