设计模式–原型(Prototype)模式Session3By佘丹1stJul2008原型(Prototype)模式通过给出一个原型对象来指明所要创建的对象类型,然后用拷贝这个原型对象的办法创建出更多的同类型对象。孙大圣的毫毛孙悟空在与黄风怪的战斗中,“使一个身外身的手段:把毫毛揪下一把,用口嚼得粉碎,望上一喷,叫声‘变’,变有百十个行者,都是一样得打扮,各执一根铁棒,把那怪围在空中。”换而言之,孙悟空可以根据自己的形象,拷贝出很多“身外身”来。孙悟空这种身外身的手段在面向对象设计领域里叫原型(Prototype)模式。1,Java对原型模式的支持在Java里面,我们可以通过Clone()方法实现原型模式。任何类,只要想支持克隆,必须实现Cloneable接口。Cloneable接口中有Clone方法,可以在类中复写实现自定义的克隆方法。克隆的实现方法有三种:浅拷贝、深拷贝和完全拷贝。(1)浅拷贝被拷贝对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅拷贝所考虑的对象,而不拷贝它所引用的对象。(2)深拷贝被拷贝对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被拷贝过的新对象,而不再是原有的那些被引用的对象。换言之,深拷贝把要拷贝的对象所引用的对象都拷贝了一遍。(3)完全拷贝完全拷贝不仅把要拷贝的对象所直接引用的对象都拷贝了一遍,还把该对象间接引用到的所有对象也都拷贝了一遍。这是最彻底的一种拷贝。2,Java的clone()方法CloneprotectedObjectclone()throwsCloneNotSupportedExceptionThismethodmaybecalledtocreateanewcopyoftheObject.Thetypicalbehaviorisasfollows:o==o.clone()isfalseo.getClass()==o.clone().getClass()istrueo.equals(o)istrueHowever,thesearenotstrictrequirements,andmaybeviolatedifnecessary.Ofthethreerequirements,thelastisthemostcommonlyviolated,particularlyifthesubclassdoesnotoverrideequals(Object)55.IftheObjectyoucallclone()ondoesnotimplementCloneable(whichisaplaceholderinterface),thenaCloneNotSupportedExceptionisthrown.NoticethatObjectdoesnotimplementCloneable;thismethodexistsasaconvenienceforsubclassesthatdo.Object'simplementationofcloneallocatesspaceforthenewObjectusingthecorrectclass,withoutcallinganyconstructors,andthenfillsinallofthenewfieldvalueswiththeoldfieldvalues.Thus,itisashallowcopy.However,subclassesarepermittedtomakeadeepcopy.AllarraytypesimplementCloneable,andoverridethismethodasfollows(itshouldneverfail):publicObjectclone(){try{super.clone();}catch(CloneNotSupportedExceptione){thrownewInternalError(e.getMessage());}}2,Java的clone()方法3,Java的类拷贝实现代码classStudentimplementsCloneable{Stringname;intage;Student(Stringname,intage){this.name=name;this.age=age;}publicObjectclone(){Objecto=null;try{o=(Student)super.clone();//Object中的clone()识别出你要复制的是哪一个对象。}catch(CloneNotSupportedExceptione){System.out.println(e.toString());}returno;}}publicstaticvoidmain(String[]args){Students1=newStudent(“zhangsan”,18);Students2=(Student)s1.clone();s2.name=“lisi”;s2.age=20;System.out.println(“name=”+s1.name+“,”+“age=”+s1.age);//修改学生2后,不影响学生1的值。}①为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。②继承自java.lang.Object类的clone()方法是浅复制。后面的代码可以证明。浅拷贝3,Java的类拷贝实现代码classProfessor{Stringname;intage;Professor(Stringname,intage){this.name=name;this.age=age;}}classStudentimplementsCloneable{Stringname;//常量对象。intage;Professorp;//...