
用一个已经创建的实例作为原型,克隆(clone)该原型对象来创建一个和原型相同或相似的新对象,免去创建对象的复杂过程和细节。原型模式分浅拷贝与深拷贝两种。
浅拷贝实现方式:
1.原型类实现CLoneable接口
2.拷贝对象通过原型的clone方法获得新的实例
深拷贝实现方式:
1.原型类实现CLoneable接口
2.原型类重写clone方法,并在克隆对象同时也克隆响应的引用类型成员变量。
————————————–
以下通过国宝熊猫的克隆来理解浅拷贝与深拷贝:
熊猫类包含两个成员属性:熊猫名字与饲养员。熊猫名字为普通字符串对象,饲养员为引用对象。以下分别通过浅拷贝和深拷贝两种方式克隆熊猫对象:
浅拷贝方式:
package net.mosang.prototype;
public class Panda implements Cloneable {
protected Object clone() throws CloneNotSupportedException {
Panda panda = (Panda) super.clone();
public String getName() {
public void setName(String name) {
public Feeder getFeeder() {
public void setFeeder(Feeder feeder) {
public Panda(String name, Feeder feeder) {
package net.mosang.prototype;
import java.util.Date;
/**
*
* @author heiry
*
*/
public class Panda implements Cloneable {
private String name;
private Feeder feeder;
//重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
Panda panda = (Panda) super.clone();
return panda;
}
//setter、getter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Feeder getFeeder() {
return feeder;
}
public void setFeeder(Feeder feeder) {
this.feeder = feeder;
}
//构造方法
public Panda(String name, Feeder feeder) {
super();
this.name = name;
this.feeder = feeder;
}
}
package net.mosang.prototype;
import java.util.Date;
/**
*
* @author heiry
*
*/
public class Panda implements Cloneable {
private String name;
private Feeder feeder;
//重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
Panda panda = (Panda) super.clone();
return panda;
}
//setter、getter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Feeder getFeeder() {
return feeder;
}
public void setFeeder(Feeder feeder) {
this.feeder = feeder;
}
//构造方法
public Panda(String name, Feeder feeder) {
super();
this.name = name;
this.feeder = feeder;
}
}
package net.mosang.prototype;
System.out.println("feed panda....");
public Feeder(String name) {
package net.mosang.prototype;
public class Feeder {
public String name;
public void feed() {
System.out.println("feed panda....");
}
public Feeder(String name) {
super();
this.name = name;
}
}
package net.mosang.prototype;
public class Feeder {
public String name;
public void feed() {
System.out.println("feed panda....");
}
public Feeder(String name) {
super();
this.name = name;
}
}
package net.mosang.prototype;
public static void main(String[] args) throws CloneNotSupportedException {
Feeder feeder = new Feed<span style="font-size:0px; color:#ff0000;"><a href="https://www.cialisrr.com/">犀利士</a>
Panda p1 = new Panda("pangpang",feeder);
Panda p2 = (Panda) p1.clone();
System.out.println("p1----->"+p1+"p1饲养员:----->"+p1.getFeeder().name);
System.out.println("p2----->"+p2+"p2饲养员:----->"+p2.getFeeder().name);
package net.mosang.prototype;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Feeder feeder = new Feed<span style="font-size:0px; color:#ff0000;"><a href="https://www.cialisrr.com/">犀利士</a>
</span>er("张大胖");
Panda p1 = new Panda("pangpang",feeder);
Panda p2 = (Panda) p1.clone();
System.out.println(p1);
System.out.println(p2);
feeder.name = "张小胖";
System.out.println("p1----->"+p1+"p1饲养员:----->"+p1.getFeeder().name);
System.out.println("p2----->"+p2+"p2饲养员:----->"+p2.getFeeder().name);
}
}
package net.mosang.prototype;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Feeder feeder = new Feed犀利士
er("张大胖");
Panda p1 = new Panda("pangpang",feeder);
Panda p2 = (Panda) p1.clone();
System.out.println(p1);
System.out.println(p2);
feeder.name = "张小胖";
System.out.println("p1----->"+p1+"p1饲养员:----->"+p1.getFeeder().name);
System.out.println("p2----->"+p2+"p2饲养员:----->"+p2.getFeeder().name);
}
}
运行结果:
net.mosang.prototype.Panda@15db9742
net.mosang.prototype.Panda@6d06d69c
p1----->net.mosang.prototype.Panda@15db9742p1饲养员:----->张小胖
p2----->net.mosang.prototype.Panda@6d06d69cp2饲养员:----->张小胖
net.mosang.prototype.Panda@15db9742
net.mosang.prototype.Panda@6d06d69c
p1----->net.mosang.prototype.Panda@15db9742p1饲养员:----->张小胖
p2----->net.mosang.prototype.Panda@6d06d69cp2饲养员:----->张小胖
net.mosang.prototype.Panda@15db9742
net.mosang.prototype.Panda@6d06d69c
p1----->net.mosang.prototype.Panda@15db9742p1饲养员:----->张小胖
p2----->net.mosang.prototype.Panda@6d06d69cp2饲养员:----->张小胖
可见浅拷贝方式,虽然获得了一个与原型对象一样的新对象,但是对于引用类型成员变量feeder,拷贝的是地址而不是对象本身,换句话说,两个对象的feeder指向的是同一个Feeder对象。
深拷贝方式:
重点在于重写原型类的clone方法:
package net.mosang.prototype;
public class Panda implements Cloneable{
//重写clone方法,并将引用成员变量feeder同时克隆
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
Panda panda = (Panda) obj ;
panda.feeder = (Feeder)this.feeder.clone();
public String getName() {
public void setName(String name) {
public Feeder getFeeder() {
public void setFeeder(Feeder feeder) {
public Panda(String name, Feeder feeder) {
package net.mosang.prototype;
/**
*
* @author heiry
*
*/
public class Panda implements Cloneable{
private String name;
private Feeder feeder;
//重写clone方法,并将引用成员变量feeder同时克隆
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
Panda panda = (Panda) obj ;
panda.feeder = (Feeder)this.feeder.clone();
return panda;
}
//setter、getter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Feeder getFeeder() {
return feeder;
}
public void setFeeder(Feeder feeder) {
this.feeder = feeder;
}
//构造方法
public Panda(String name, Feeder feeder) {
super();
this.name = name;
this.feeder = feeder;
}
}
package net.mosang.prototype;
/**
*
* @author heiry
*
*/
public class Panda implements Cloneable{
private String name;
private Feeder feeder;
//重写clone方法,并将引用成员变量feeder同时克隆
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
Panda panda = (Panda) obj ;
panda.feeder = (Feeder)this.feeder.clone();
return panda;
}
//setter、getter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Feeder getFeeder() {
return feeder;
}
public void setFeeder(Feeder feeder) {
this.feeder = feeder;
}
//构造方法
public Panda(String name, Feeder feeder) {
super();
this.name = name;
this.feeder = feeder;
}
}
package net.mosang.prototype;
public class Feeder implements Cloneable{
System.out.println("feed panda....");
public Feeder(String name) {
protected Object clone() throws CloneNotSupportedException {
package net.mosang.prototype;
public class Feeder implements Cloneable{
public String name;
public void feed() {
System.out.println("feed panda....");
}
public Feeder(String name) {
super();
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package net.mosang.prototype;
public class Feeder implements Cloneable{
public String name;
public void feed() {
System.out.println("feed panda....");
}
public Feeder(String name) {
super();
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package net.mosang.prototype;
public static void main(String[] args) throws CloneNotSupportedException {
Feeder feeder = new Feeder("张大胖");
Panda p1 = new Panda("pangpang",feeder);
Panda p2 = (Panda) p1.clone();
System.out.println("p1----->"+p1+"p1饲养员:----->"+p1.getFeeder().name);
System.out.println("p2----->"+p2+"p2饲养员:----->"+p2.getFeeder().name);
package net.mosang.prototype;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Feeder feeder = new Feeder("张大胖");
Panda p1 = new Panda("pangpang",feeder);
Panda p2 = (Panda) p1.clone();
System.out.println(p1);
System.out.println(p2);
feeder.name = "张小胖";
System.out.println("p1----->"+p1+"p1饲养员:----->"+p1.getFeeder().name);
System.out.println("p2----->"+p2+"p2饲养员:----->"+p2.getFeeder().name);
}
}
package net.mosang.prototype;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Feeder feeder = new Feeder("张大胖");
Panda p1 = new Panda("pangpang",feeder);
Panda p2 = (Panda) p1.clone();
System.out.println(p1);
System.out.println(p2);
feeder.name = "张小胖";
System.out.println("p1----->"+p1+"p1饲养员:----->"+p1.getFeeder().name);
System.out.println("p2----->"+p2+"p2饲养员:----->"+p2.getFeeder().name);
}
}
运行结果:
net.mosang.prototype.Panda@15db9742
net.mosang.prototype.Panda@6d06d69c
p1----->net.mosang.prototype.Panda@15db9742p1饲养员:----->张小胖
p2----->net.mosang.prototype.Panda@6d06d69cp2饲养员:----->张大胖
net.mosang.prototype.Panda@15db9742
net.mosang.prototype.Panda@6d06d69c
p1----->net.mosang.prototype.Panda@15db9742p1饲养员:----->张小胖
p2----->net.mosang.prototype.Panda@6d06d69cp2饲养员:----->张大胖
net.mosang.prototype.Panda@15db9742
net.mosang.prototype.Panda@6d06d69c
p1----->net.mosang.prototype.Panda@15db9742p1饲养员:----->张小胖
p2----->net.mosang.prototype.Panda@6d06d69cp2饲养员:----->张大胖
可以看到,深拷贝的引用类型成员变量也是各自独立的。