I should note to begin with that clone
in and of itself is broken, and that a copy constructor, like Sheep(Sheep cloneMe)
is a far more elegant idiom than clone
, considering the Cloneable
contract is very weak. You probably already know this, since you're reading the book, but it's worth putting in here.
Anyway, to answer the question:
Object.clone()
will create an object of the same type as the object it was called on. For this reason, it is strongly encouraged to "cascade" up to Object
for getting the result you plan to return. If someone decides to not follow this convention, you will end up with an object of the type of the class that broke the convention, which will cause a multitude of problems.
To illustrate I have a class like so
class Sheep implements Cloneable {
Sheep(String name)...
public Object clone() {
return new Sheep(this.name); // bad, doesn't cascade up to Object
}
}
class WoolySheep extends Sheep {
public Object clone() {
return super.clone();
}
}
Suddenly, if I do
WoolySheep dolly = new WoolySheep("Dolly");
WoolySheep clone = (WoolySheep)(dolly.clone()); // error
I'll get an exception because what I get back from dolly.clone()
is a Sheep
, not a WoolySheep
.