posted 16 years ago
Having worked with both C++ and Java, I can only give you my opinion of advantages/disadvantages, not the "reason" it was decided.
A single hierarchy for class types makes it possible to create generic containers. This is in contrast to C++'s type-specific containers, which are created using templates. Functionally, it means that the same code is used whether you have an ArrayList of Customers, or an ArrayList of Invoices. From a practical standpoint, this has two effects:
1. The developer has to be sure to maintain the homogeneity of the collection, and not allow unrelated objects into it. Until Java 1.5, this could only be determined at runtime, by catching a ClassCastException. In Java 1.5, a new collection strategy allowed the created of type-specific containers that could enforce the homogeneity at compile time, which meant that you couldn't put an object in a container of an inappropriate type. The fact that this would be caught at compile time was considered A Good Thing.
2. Unlike C++, Java pretty much requires you to downcast. When you put an object in a container (pre-1.5), its type "disappeared"...any method to retrieve the object returned an Object type, which would then need to be downcast. As a former C++ developer, I learned that downcasting was inappropriate for most things in an OO world...the object ought to be able to behave according to its type with me having to tell it its type. In effect, downcasting in C++ was almost always incorrect because proper design would result in a polymorphic strategy that eliminates the need for downcasting.
Another advantage of the single hierarchy is the built in support for things like threading, cloning, tests of equality, etc. With C++'s multiple inheritance feature, it would certainly be easy to graft on any of those features to an existing class, but in Java it it built in. C++ was not inherently multi-threaded, so there was no need to have support for that feature in all objects. Also, C++ does not have a polymorphic copy constructor, which means that it is difficult to copy a collection of different types. Java's containers (again, pre-1.5) were designed to hold objects of any type, so the feature enabling polymorphic cloning made sense (in my experience, the percentage of times I need a polymorphic copy method is extremely small).
One thing I think bigots (either Java or C++) fail to appreciate is that either language can gracefully solve most programming problems faced in a typical development environment. The design of each language makes the strategy differ from one language to another. I might have to jump through a few more hoops to do something in one language that is more graceful in another one, but each one has its strength and weaknesses anyway.