4. 原型模式

使用原型去拷贝出多个对象

克隆羊案例:

/**
 * @author wuyimin
 * @create 2021-07-25 16:51
 * @description 实现克隆接口,调用父类的克隆方法
 */
public class Sheep implements Cloneable {
    String name;
    int age;

    public Sheep(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Sheep() {
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    protected Sheep clone() throws CloneNotSupportedException {
        Sheep sheep=null;
        sheep=(Sheep) super.clone();
        return sheep;
    }
}

浅拷贝问题--修改原型引用传递的值会导致拷贝的对象的值也跟着改变

/**
 * @author wuyimin
 * @create 2021-07-25 16:51
 * @description 实现克隆接口
 */
public class Sheep implements Cloneable {
    String name;
    int age;
    //新增friend属性
    Sheep friend;

    public Sheep getFriend() {
        return friend;
    }

    public void setFriend(Sheep friend) {
        this.friend = friend;
    }

    public Sheep(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Sheep() {
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    protected Sheep clone() throws CloneNotSupportedException {
        Sheep sheep=null;
        sheep=(Sheep) super.clone();
        return sheep;
    }
}
/**
 * @author wuyimin
 * @create 2021-07-25 16:53
 * @description 测试
 */
public class MyTest {
    @Test
    public void test() throws CloneNotSupportedException {
        Sheep sheep = new Sheep("多利",3);
        sheep.setFriend(new Sheep("刘子",2));
        Sheep clone = sheep.clone();
        //对于浅拷贝会直接拿到引用传递的地址进行拷贝
        System.out.println(clone.getFriend() == sheep.getFriend());//true
        System.out.println(clone);
    }
}

深拷贝的两种实现方式-序列化、重写clone方法 

A类依赖于B类

重写clone方法

/**
 * @author wuyimin
 * @create 2021-07-25 17:22
 * @description 这里因为测试类不在一个包下面把方法改成public了
 */
public class A implements Cloneable,Serializable{
    private String aName;
    private B bObject;

    public A(String aName, B bObject) {
        this.aName = aName;
        this.bObject = bObject;
    }

    public String getaName() {
        return aName;
    }

    public void setaName(String aName) {
        this.aName = aName;
    }

    public B getbObject() {
        return bObject;
    }

    public void setbObject(B bObject) {
        this.bObject = bObject;
    }

    @Override
    public A clone() throws CloneNotSupportedException {
        A a=null;
        a=(A) super.clone();
        a.bObject=bObject.clone();
        return a;
    }
}

/**
 * @author wuyimin
 * @create 2021-07-25 17:23
 * @description 这里因为测试类不在一个包下面把方法改成public了
 *
 */
public class B implements Cloneable,Serializable{
    String bName;

    public B(String bName) {
        this.bName = bName;
    }

    @Override
    public B clone() throws CloneNotSupportedException {
        B b=null;
        b=(B)super.clone();
        return b;
    }
}

测试

@Test
    public void test2() throws CloneNotSupportedException {
        A a=new A("111",new B("111"));
        A clone = a.clone();
        System.out.println(a.getbObject()==clone.getbObject());//false

    }

序列化方式(推荐)

/**
 * @author wuyimin
 * @create 2021-07-25 17:22
 * @description 序列化方法
 */
public class A implements Serializable {
    private String aName;
    private B bObject;

    public A(String aName, B bObject) {
        this.aName = aName;
        this.bObject = bObject;
    }

    public String getaName() {
        return aName;
    }

    public void setaName(String aName) {
        this.aName = aName;
    }

    public B getbObject() {
        return bObject;
    }

    public void setbObject(B bObject) {
        this.bObject = bObject;
    }

    public A deepClone() {
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        try {
            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            //反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            A o = (A) ois.readObject();
            return o;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            //从下往上关闭流
            try {
                ois.close();
                bis.close();
                oos.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

posted @ 2021-07-25 18:03  一拳超人的逆袭  阅读(35)  评论(0编辑  收藏  举报