上海网站优化公司,沪佳装修口碑怎么样,网站建设维护公司,即墨哪里有做网站的Java为我们提供了各种各样功能的接口#xff0c;Clonable接口就是其中之一。
它通常配合Object类的 clone方法使用。这个方法可以为我们创建一个对象的拷贝#xff0c;即复制一个对象。在进入本文的主要内容之前#xff0c;先来对访问限定符 protected进行一个解剖。
1.再…Java为我们提供了各种各样功能的接口Clonable接口就是其中之一。
它通常配合Object类的 clone方法使用。这个方法可以为我们创建一个对象的拷贝即复制一个对象。在进入本文的主要内容之前先来对访问限定符 protected进行一个解剖。
1.再谈 protected
我们知道在一个类中被 protected修饰的字段和方法它们的访问权限如下 本类内部本类内部的所有成员都能够访问被protected修饰的元素。同一个包内同一包中的其他类不管是子类还是非子类都可以访问该元素。不同包的子类若子类与父类不在同一个包中子类可以通过继承或者创建子类对象的方式来访问父类的 protected成员。 这里重点讨论第三点当一个类中有被 protected修饰的字段和方法并且它的子类与它在不同包时那么子类只能在自身内部去调用父类的 protected成员不能在外部调用。
举个例子如下
//父类 Animal位于Demo1包
package Demo1;public class Animal {private String name;private int age;public Animal(String name, int age) {this.name name;this.age age;}protected void eat() {System.out.println(this.name 正在吃饭....);}
}//子类 Dog位于Demo2包package Demo2;import Demo1.Animal;public class Dog extends Animal {public Dog(String name, int age) {super(name, age);}public void eat1() {super.eat();}
}//测试类 Testimport Demo2.Dog;public class Test {public static void main(String[] args) {Dog dog new Dog(大黄,1);//dog.eat();发生错误java: eat() 在 Demo1.Animal 中是 protected 访问控制dog.eat1();//正常运行运行结果大黄正在吃饭....}
}我们可以发现确实如此eat()方法是父类Animal中被protected修饰的方法不能在子类Dog类外部直接调用像这样dog.eat()只能在子类内部调用只有在子类内部的方法中去调用父类Animal像这样eat1()中的super.eat();这样Dog类外部使用 dog.eat1()就可以间接调用父类Animal的eat()方法。
当然我们也可以对在子类中对父类的protected方法进行重写这样在子类外部就能直接调用了。这里就不再举例了。 2. 如何进行克隆
要使用Object类的clone方法我们通常需要做以下几件事 在要克隆的类中重写Object类的 clone方法实现 Cloneable接口事先处理异常情况 现在有一个Person类,我们打算克隆它的一个对象。
1.在要克隆的类中重写Object类的 clone方法
package Demo3;public class Person {public String name;public Person(String name) {this.name name;}//重写 clone方法Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}注可以通过快捷键“Alt Insert”快速重写 clone方法。 2.实现 Cloneable接口
package Demo3;public class Person implements Cloneable{private String name;public Person(String name) {this.name name;}Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}注当我们进入 Cloneable接口时会发现它是一个空接口它的作用是 宣布实现了这个接口的类可以克隆。 3.处理异常情况我们创建一个测试类在测试类中去克隆一个Person对象。
package Demo3;public class Test {public static void main(String[] args) throws CloneNotSupportedException{Person person1 new Person(小明);Person person2 (Person) person1.clone();}
}
//这里需要做两件事
//1.把重写的 clone方法中的throws CloneNotSupportedException 这个部分复制到 mian方法后面。
//2.因为重写的 clone方法的返回值为 Object因此这里需要强转。
让我们测试一下
package Demo3;public class Test {public static void main(String[] args) throws CloneNotSupportedException{Person person1 new Person(小明);Person person2 (Person) person1.clone();System.out.println(person1的名字 person1.name);System.out.println(person2的名字 person2.name);}
}//运行结果
person1的名字小明
person2的名字小明
显然确实做到克隆一份person1。
那么它的过程是怎么样的呢我们通过图画的方式来说明 3. 浅拷贝
知道了如何进行克隆接着我们来讨论一下什么是浅拷贝顾名思义可以理解为浅度的克隆。
举个例子我们在创建一个新的类 Money在 Person类中创建一个 money对象并将它作为一个字段。
//Money类package Demo3;public class Money {public int m 10;
}//Person类package Demo3;public class Person implements Cloneable{public String name;public Money money new Money();public Person(String name) {this.name name;}Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}现在我们再去克隆接着修改person2对象当中的money对象的m看看结果如何。
package Demo3;public class Test {public static void main(String[] args) throws CloneNotSupportedException{Person person1 new Person(小明);Person person2 (Person) person1.clone();System.out.println(person1的m person1.money.m);System.out.println(修改前的person2的m person2.money.m);person2.money.m 100;System.out.println();System.out.println(person1的m person1.money.m);System.out.println(修改后的person2的m person2.money.m);}
}//运行结果
person1的m10
修改前的person2的m10person1的m100
修改后的person2的m100
我们可以发现person1与person2公用一个 money.m,因为person1和person2的money引用指向同一个对象。对于它的过程我们依旧可以用画图的方式表示 4. 深拷贝 在浅拷贝的例子里我们会发现 person1和 person2公用一个 money.m原因是它们的 money引用中储存的是同一个money对象的地址。现在我们不想它们公用一个 money.m那么我们该怎么做呢这里我们就需要实现深拷贝。
想要实现深拷贝要做两件事 要进行拷贝的类都要重写 clone方法和实现 Cloneable接口例如作为 Person类字段的 Money类也要重写clone方法。修改主要的类的重写的clone方法例如 上述例子中的 Person类它是主要的类因为Money类是它的字段。 在Money类中重写 clone方法和实现 Cloneable接口。 package Demo3;public class Money implements Cloneable{public int m 10;//重写 clone方法Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}修改 Person类中的重写的 clone方法。
package Demo3;public class Person implements Cloneable{public String name;public Money money new Money();public Person(String name) {this.name name;}Overrideprotected Object clone() throws CloneNotSupportedException {Person temp (Person) super.clone(); temp.money (Money) this.money.clone();return temp;}
}//说明这里先创建一个 Person类型的变量 temp用来接收克隆的person对象
//接着让temp.money去接收克隆的money对象最后返回 temp变量。
现在我们再去克隆接着修改person2对象当中的money对象的m看看结果如何。
package Demo3;public class Test {public static void main(String[] args) throws CloneNotSupportedException{Person person1 new Person(小明);Person person2 (Person) person1.clone();System.out.println(person1的m person1.money.m);System.out.println(修改前的person2的m person2.money.m);person2.money.m 100;System.out.println();System.out.println(person1的m person1.money.m);System.out.println(修改后的person2的m person2.money.m);}
}//运行结果
person1的m10
修改前的person2的m10person1的m10
修改后的person2的m100
显然此时修改 person2的 money.m也不会影响person1因为person2的 money对象是克隆person1的不再是与person1公用了。对于它的过程我们用图画表示如下 到此本文完。本文若有不对的地方还请各位看官指出多谢