Reputation: 189
I have a two simple Java classes and I am trying to understand more about cloning and how to cast between different levels of classes. This is the superclass Vehicle.
public class Vehicle implements Cloneable
{
public int x;
public Vehicle(int y) {
x = y;
}
@Override public Object clone() {
Object result = new Vehicle(this.x);
// Location "A"
return result;
}
}
And this is the subclass Truck
public class Truck extends Vehicle
{
private int y;
public Truck(int z) {
super(z);
y = z;
}
@Override public Object clone() {
Object result = super.clone();
System.out.println(result.getClass());
((Truck) result).y = this.y;
return result;
}
}
I am trying to get a copy of Truck while using the superclass to clone but having issues with downcasting not being allowed. I am not really sure how to fix this or where the error is.
I would like to have: Truck a = new Truck(1) and Truck b = a.clone() become the same object.
Upvotes: 0
Views: 1978
Reputation: 2454
When you cast from one class to another, you are not changing the actual object, but making it accessible in a different way.
class A { public int x; }
class B extends A { public int y; }
A a = new A();
B aB = new B();
System.out.println(aB); // A@...
System.out.println(aB.y); // throws an error
When you call super.clone()
, it creates a Vehicle
instance, and Vehicle
instances do not have y
.
Instead, you probably want to initiate the object and not call super.clone()
in Truck.clone
:
return new Vehicle(this.y);
Upvotes: 0
Reputation: 50716
You're misusing clone()
. All the instantiation and field copying is done by the super
implementation when you implement Cloneable
. Your Vehicle
implementation should look like this:
@Override
public Vehicle clone() {
try {
return (Vehicle)super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
And you can optionally override it in Truck
like this:
@Override
public Truck clone() {
return (Truck)super.clone();
}
Upvotes: 3