原型模式——Java实现
向量的原型
用C++完成数学中向量的封装,其中,用指针和动态申请支持向量长度的改变,使用浅克隆和深克隆复制向量类,比较这两种克隆方式的异同。
浅克隆类图:
//Vector.java package qiankelong; import java.util.Arrays; public class Vector implements Cloneable { private int[] array; private Attachment attachment=null; public Vector() { this.attachment=new Attachment(); } public Object clone() { Vector clone=null; try { clone=(Vector)super.clone(); } catch(CloneNotSupportedException e) { System.out.println("Clone failure!"); } return clone; } public Attachment getAttachment() { return this.attachment; } public void display() { System.out.println(Arrays.toString(array)); } public int[] getArray() { return array; } public void setArray(int[] array) { this.array = array; } } //Attachment.java package qiankelong; public class Attachment { public void download() { System.out.println("复制向量"); } } //Client.java package qiankelong; public class Client { public static void main(String a[]) { Vector vector,copyVector; vector=new Vector(); int[] arr= {2,8,3,6}; vector.setArray(arr); System.out.println("浅克隆示例:"); copyVector=(Vector)vector.clone(); System.out.print("vector:"); vector.display(); System.out.print("copyVector:"); copyVector.display(); System.out.println("vector==copyVector?"); System.out.println(vector==copyVector); System.out.println("vector.getAttachment==copyVector.getAttachment?"); System.out.println(vector.getAttachment()==copyVector.getAttachment()); } }
浅克隆运行结果:
深克隆类图
深克隆java代码:
package shenkelong; import java.io.*; import java.util.Arrays; public class Vector implements Serializable { private int[] array; private Attachment attachment=null; public Vector() { this.attachment=new Attachment(); } public Object deepClone() throws IOException, ClassNotFoundException, OptionalDataException { //将对象写入流中 ByteArrayOutputStream bao=new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(bao); oos.writeObject(this); //将对象从流中取出 ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray()); ObjectInputStream ois=new ObjectInputStream(bis); return(ois.readObject()); } public Attachment getAttachment() { return this.attachment; } public void display() { System.out.println(Arrays.toString(array)); } public int[] getArray() { return array; } public void setArray(int[] array) { this.array = array; } } //Attachment.java package shenkelong; import java.io.*; public class Attachment implements Serializable { public void download() { System.out.println("复制向量"); } } //Client.java package shenkelong; public class Client { public static void main(String a[]) { Vector vector,copyVector=null; vector=new Vector(); int[] arr= {2,8,3,6}; vector.setArray(arr); System.out.println("深克隆示例:"); try{ copyVector=(Vector)vector.deepClone(); } catch(Exception e) { e.printStackTrace(); } System.out.print("vector:"); vector.display(); System.out.print("copyVector:"); copyVector.display(); System.out.println("vector==copyVector?"); System.out.println(vector==copyVector); System.out.println("vector.getAttachment==copyVector.getAttachment?"); System.out.println(vector.getAttachment()==copyVector.getAttachment()); } }
深克隆运行结果:
两种的异同:
1、Java中所有的类都继承自java.lang.Object,而Object类提供一个clone()方法,可以将一个Java对象复制一份。因此在Java中可以直接使用Object提供的clone()方法来实现对象的克隆。
2、浅克隆:复制对象时仅仅复制对象本身,包括基本属性,但该对象的属性引用其他对象时,该引用对象不会被复制,即拷贝出来的对象与被拷贝出来的对象中的属性引用的对象是同一个。
Vector对象实现Cloneable并重写clone方法:
copyVector和vector所引用的Attachment对象是同一个对象
3、深克隆:复制对象本身的同时,也复制对象包含的引用指向的对象,即修改被克隆对象的任何属性都不会影响到克隆出来的对象。
使用对象流将对象写入流然后再读出是进行的深克隆。
copyVector和vector所引用的Attachment对象不是同一个对象