重写clone方法时,为什么需要在Java中将其声明为public?
**clone()** 方法属于java.lang包中名为Object的类,它接受一个对象作为参数,创建一个并返回它的副本。
为了使用此方法,您需要确保您的类实现了Cloneable(标记)接口。
示例
public class CloneExample implements Cloneable {
private String name;
private int age;
public CloneExample(String name, int age){
this.name = name;
this.age = age;
}
public void displayData(){
System.out.println("Name : "+this.name);
System.out.println("Age : "+this.age);
}
public static void main(String[] args) throws CloneNotSupportedException {
CloneExample std = new CloneExample("Krishna", 25);
System.out.println("Contents of the original object");
std.displayData();
System.out.println("Contents of the copied object");
CloneExample copiedStd = (CloneExample) std.clone();
copiedStd.displayData();
}
}输出
Contents of the original object Name : Krishna Age : 25 Contents of the copied object Name : Krishna Age : 25
使用clone方法,您可以执行两种类型的复制:
- 浅复制 - 复制对象时,如果它包含任何对象作为字段,则只复制对这些对象的引用,而不是完整的对象。默认情况下,**clone()** 方法执行浅复制。
- 深复制 - 在深复制中,原始对象的全部字段都被精确复制,此外,如果它包含任何对象作为字段,则也会创建它们的副本(使用clone()方法)。
因此,要执行深复制,您需要重写Object类的clone()方法。
clone()方法的访问修饰符
java.lang.Object 类中的clone()方法是受保护的(protected)。方法之前的protected修饰符使其仅对当前类的子类可见。由于Object是Java中所有类的超类,因此在Object类中的clone()方法之前使用protected修饰符是有意义的。
如果您重写Object类的clone()方法并将其声明为protected,则它仅对当前类的子类可见。
示例
假设我们在名为**myPackage1**的包中拥有两个类,名为Contact和StudentData,如下所示。
Contact.java
package myPackage1;
public class Contact implements Cloneable{
private long phoneNo;
private String email;
public Contact(long phoneNo, String email ){
this.phoneNo = phoneNo;
this.email = email;
}
public void displayContact() {
System.out.println("Phone no: "+this.phoneNo);
System.out.println("Email: "+this.email);
}
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}StudentData.java
package myPackage1;
public class StudentData implements Cloneable {
private String name;
private int age;
private Contact contact;
public StudentData(String name, int age, Contact contact){
this.name = name;
this.age = age;
this.contact = contact;
}
public void displayData(){
System.out.println("Name : "+this.name);
System.out.println("Age : "+this.age);
contact.displayContact();
}
protected Object clone() throws CloneNotSupportedException{
StudentData student = (StudentData) super.clone();
student.contact = (Contact) contact.clone();
return student;
}
}您可以编译以上两个类:
D:\>javac -d . Contact.java D:\>javac -d . StudentData.java
从另一个名为myPackage的包中的类,我们尝试访问StudentData类的clone()方法,如下所示:
示例
package myPackage2;
import myPackage1.Contact;
import myPackage1.StudentData;
public class CloneExample{
public static void main(String[] args) throws CloneNotSupportedException {
//Creating an object of the class
StudentData std = new StudentData("Krishna", 25, new Contact(9848022338L, "Krishna_test@mymail.com"));
//Creating a clone of the above object
StudentData copiedStd = (StudentData) std.clone();
System.out.println("Contents of the copied object::");
copiedStd.displayData();
System.out.println(" ");
System.out.println("Contents of the original object::");
std.displayData();
}
}编译时错误
当您尝试编译上面的类时,由于您尝试访问实现的clone()方法(它被声明为protected),并且是从另一个包中访问的,因此会生成编译时错误,如下所示:
D:\>javac -d . CloneExample.java CloneExample.java:10: error: clone() has protected access in StudentData StudentData copiedStd = (StudentData) std.clone(); ^ 1 error
因此,在重写clone()方法时,建议将其声明为public而不是protected,以便可以从系统中任何位置的类访问它。
在重写方法时,子类中的方法不能比超类中的方法具有更高的访问限制。由于public的限制比protected低,因此允许将重写方法中的访问修饰符从protected更改为public。
广告
数据结构
网络
关系型数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP