原型模式的核心是如何实现拷贝
public class PrototypeClass implements Cloneable
{
public PrototypeClass clone()
{
PrototypeClass prototypeClass = null;
try
{
prototypeClass = (PrototypeClass) super.clone();
} catch (CloneNotSupportedException exception)
{
exception.printStackTrace();
}
return prototypeClass;
}
}
package com.lzhsite.technology.deepcopy;
/**
* 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
* 深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,
* B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,
* 深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。
* 若不对clone()方法进行改写,则调用此方法得到的对象即为浅拷贝,下面我们着重谈一下深拷贝
*
* 注意:深复制只针自定义对象,基本数据类型的对象默认都是深复制
*/
class Professor0 implements Cloneable {
String name;
int age;
Professor0(String name, int age) {
this.name = name;
this.age = age;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Student0 implements Cloneable {
String name;// 常量对象。
int age;
Professor0 p;// 学生1和学生2的引用值都是一样的。
Student0(String name, int age, Professor0 p) {
this.name = name;
this.age = age;
this.p = p;
}
public Object clone() {
Student0 o = null;
try {
o = (Student0) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
return o;
}
}
public class ShallowCopy {
public static void main(String[] args) {
Professor0 p = new Professor0("wangwu", 50);
Student0 s1 = new Student0("zhangsan", 18, p);
Student0 s2 = (Student0) s1.clone();
s2.p.name = "lisi";
s2.p.age = 30;
s2.name = "z";
s2.age = 45;
System.out.println("学生s1的姓名:" + s1.name + "\n学生s1教授的姓名:" + s1.p.name + "," + "\n学生s1教授的年纪" + s1.p.age);// 学生1的教授
}
}
预想输出:
学生s1的姓名:zhangsan
学生s1教授的姓名:wangwu,
学生s1教授的年纪50
结果输出:
学生s1的姓名:zhangsan
学生s1教授的姓名:lisi,
学生s1教授的年纪30
下面来通过一个实例来理解下深浅拷贝:
public class Client {
public static void main(String args []) throws CloneNotSupportedException {
DogClone dogClone = new DogClone();
dogClone.legCounts = 3;
System.out.println("原来的克隆狗腿数量:"+dogClone.legCounts);
System.out.println("原来的普通狗腿的数量:"+dogClone.dog);//Dog的toString方法返回的值。
DogClone dogClone1 = (DogClone)dogClone.clone();
dogClone1.legCounts=2 ;
Dog dog = dogClone1.dog;
dog.changeLegCounts();
System.out.println("克隆后原来狗腿数量:"+dogClone.legCounts);
/**
* 出现的结果是:8
* 原因很简单就是dog是一个引用,改变一个对象的话,会改变另一个对象。
*/
System.out.println("克隆后原来普通狗的数量:"+ dogClone.dog);
System.out.println("克隆后克隆狗腿的数量:"+ dogClone1.legCounts);
/**
*改变源:改变了自身dogClone.dog,影像了对象dogClone.dog 的值,
*/
System.out.println("克隆后普通狗的数量:"+ dogClone1.dog);
}
}
/**
* 未实现了克隆方法的类和实现克隆方法的类做比较
*
*/
public class Dog {
/**
* 狗腿条数
*/
public int legCounts;
public Dog(int legCounts) {
this.legCounts = legCounts;
}
/**
* 改变狗的腿数量
*/
public void changeLegCounts(){
this.legCounts *=2;
}
public String toString () {
return Integer.toString(this.legCounts);
}
}
public class DogClone implements Cloneable {
/**
* 狗腿条数
*/
public int legCounts;
/**
* 初始化一个狗
*/
Dog dog = new Dog(4);
@Override
protected DogClone clone() throws CloneNotSupportedException {
return (DogClone)super.clone();
}
}
输出结果:
原来的克隆狗腿数量:3
原来的普通狗腿的数量:4
克隆后原来狗腿数量:3
克隆后原来普通狗的数量:8
克隆后克隆狗腿的数量:2
克隆后普通狗的数量:8
让Doc实现Cloneable接口后
/**
* 该类是没有实现克隆方法的类和实现克隆方法的类做比较
*
*/
public class Dog implements Cloneable{
/**
* 狗腿条数
*/
public int legCounts;
public Dog(int legCounts) {
this.legCounts = legCounts;
}
/**
* 改变狗的腿数量
*/
public void changeLegCounts(){
this.legCounts *=2;
}
@Override
public Dog clone() throws CloneNotSupportedException {
return (Dog)super.clone();
}
public String toString () {
return Integer.toString(this.legCounts);
}
}
输出结果:
原来的克隆狗腿数量:3
原来的普通狗腿的数量:4
克隆后原来狗腿数量:3
克隆后原来普通狗的数量:4
克隆后克隆狗腿的数量:2
克隆后普通狗的数量:8
对原型模式的总结: