Code behind:
class A implements Cloneable
{
int i, j;
A(int i, int j)
{
this.i = i;
this.j = j;
}
A()
{
}
}
class B extends A
{
int l, m;
B()
{
}
B(int l, int m)
{
this.l = l;
this.m = m;
}
public static void main(String l[])
{
A obj = new A(1, 2);
B obj1 = (B) obj.clone(); // ERROR
}
}
I know that I am violating the meaning of clone as I am trying to assign the fields of one object to a completely different object. But its the error statement that is confusing me.
Statement: "error: clone() has protected access in Object"
Extending A should make clone()
available to B also ? If that is, so values of i and j should be copied to l and m also ? Is this possible ?
It is protected because the default implementation does a shallow memberwise copy of all fields (including private), circumventing constructor.
From Java 1.5 onwards an overriding method can return subclass of return type declared in original method, which means you can return sub class from clone method. It is known as co-variant method overriding.
Creating a copy using the clone() method The class whose object's copy is to be made must have a public clone method in it or in one of its parent class. Every class that implements clone() should call super. clone() to obtain the cloned object reference. The class must also implement java.
clone() method acts like a copy constructor. It creates and returns a copy of the object. Since the Object class has the clone method (protected) you cannot use it in all your classes. The class which you want to be cloned should implement clone method and overwrite it.
clone() is protected method and to make accessible in sub-classes, override it with public
access.
class A implements Cloneable{
.....
@Override
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
From Javadoc of Cloneable
By convention, classes that implement this interface should override Object.clone (which is protected) with a public method. See Object.clone() for details on overriding this method.
Note that this interface does not contain the clone method. Therefore, it is not possible to clone an object merely by virtue of the fact that it implements this interface. Even if the clone method is invoked reflectively, there is no guarantee that it will succeed.
Clone
is one of the early designs in java and it has flaws
About access- When a method is protected, it can only be accessed by the class itself, subclasses of the class, or classes in the same package as the class
.
So it is accessible in A
and B
classes the way you are doing it is only possible if you are in the same package that happens to be java.lang
You can provide some method like this inside A
.
public A copy() throws CloneNotSupportedException {
return (A) clone();
}
Correct Implementation
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
};
Also Remember parent is not type of child so casting from A to B will not work. Child is type of Parent so casting from B to A will work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With