プロトタイプパターンの使用方法

1. プロトタイプモードの使い方

1.1 はじめに

作成済みのインスタンスをプロトタイプとして使用し、プロトタイプ オブジェクトをコピーして、プロトタイプ オブジェクトと同じオブジェクトを新規作成します。

1.2 構造

  • 抽象プロトタイプ クラス: 具体的なプロトタイプ オブジェクトが実装する必要がある clone() メソッドを指定します。
  • 具象プロトタイプクラス: コピー可能なオブジェクトである抽象プロトタイプクラスの clone() メソッドを実装します。
  • アクセス クラス: 具体的なプロトタイプ クラスの clone() メソッドを使用して、新しいオブジェクトをコピーします。

1.3 プロトタイプパターンのクラス図

Java の Object クラスはclone()シャロー クローン作成を実装するメソッドを提供します。Cloneable インターフェイスはクラス図の抽象プロトタイプ クラスであり、Cloneable インターフェイスを実装するサブ実装クラスは具象プロトタイプ クラスです。

ここに画像の説明を挿入

1.4 実装

1.4.1 クローンの分類

プロトタイプ モードのクローニングは、シャロー クローニングとディープ クローニングに分けられます。

浅いクローン: 新しいオブジェクトを作成します。新しいオブジェクトの属性は元のオブジェクトとまったく同じで、非基本型属性の場合は、元の属性が指すオブジェクトのメモリ アドレスを指します。

ディープ クローン: 新しいオブジェクトが作成されると、属性で参照されている他のオブジェクトもクローン化され、元のオブジェクト アドレスを指さなくなります。

1.4.2 コード

/**
 * 具体原型类: Realizetype
 */
public class Realizetype implements Cloneable{
    
    
    // 无参构造函数,创建对象时运行里面的代码
    public Realizetype() {
    
    
        System.out.println("具体的原型对象创建完成");
    }
    @Override
    public Realizetype clone() throws CloneNotSupportedException {
    
    
        System.out.println("具体原型复制成功");
        // Object类中提供了clone()方法来实现浅克隆,强转为Realizetype
        return (Realizetype) super.clone();
    }
}

/**
 * 访问类: client
 */
public class client{
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        // 创建一个原型类的对象
        Realizetype realizetype = new Realizetype();
        // 调用Realizetype类中的clone方法进行对象的克隆
        Realizetype clone = realizetype.clone();
        System.out.println("原型对象和克隆出来的对象是否为一个对象:" + (realizetype == clone));// false
    }
}

1.5 「三優」受賞事例

1.5.1 「優秀学生三名」賞のクラス図

同じ学校の「三優」の賞状は、受賞者の名前以外は同じです。プロトタイプモードを使用して複数の「三優」の賞状をコピーし、賞状の名前を変更することができます。

ここに画像の説明を挿入

1.5.2 コード

/**
 * 学生实体类: Student
 */
public class Student {
    
    
    // 学生姓名
    private String name;

    public Student() {
    
    
    }

    public Student(String name) {
    
    
        this.name = name;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
    
    
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
    
    
        this.name = name;
    }
    
    public String toString() {
    
    
        return "Student{name = " + name + "}";
    }
}

/**
 * 具体原型类: Citation
 */
public class Citation implements Cloneable {
    
    
    private Student stu;

    public Student getStudent(){
    
    
        return stu;
    }

    public void setStudent(Student stu){
    
    
        this.stu = stu;
    }

    @Override
    public Citation clone() throws CloneNotSupportedException {
    
    
        return (Citation) super.clone();
    }

    public void show() {
    
    
        System.out.println(stu.getName() + "同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }
}

/**
 * 访问类: CitaionTest
 */
public class CitaionTest {
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        // 创建原型对象
        Citation citation = new Citation();
        // 创建张三学生对象
        Student stu = new Student();
        stu.setName("张三");
        citation.setStudent(stu);

        // 克隆奖状对象
        Citation citation1 = citation.clone();
        // 避免浅克隆的问题,重新声明一个对象
        Student stu1 = new Student();
        stu1.setName("李四");
        citation1.setStudent(stu1);

        // 调用show方法展示
        citation.show();
        citation1.show();
    }
}

1.6 深いクローンと浅いクローンの区別

1.6.1 浅いクローン

新しいオブジェクトを作成します。新しいオブジェクトの属性は元のオブジェクトとまったく同じで、非基本型属性の場合は、元の属性が指すオブジェクトのメモリ アドレスを指します。stu オブジェクトと stu1 オブジェクトは同じオブジェクトであるため、stu1 オブジェクトの name 属性の値は「Li Si」に変更され、2 つの Citation (証明書) オブジェクトには Li Si が表示されます。これは、具体的なプロトタイプ クラス (Citation) の参照型の属性をコピーする、シャロー クローン作成の効果です。

/**
 * 学生实体类: Student
 */
public class Student {
    
    
    // 学生姓名
    private String name;

    public Student() {
    
    
    }

    public Student(String name) {
    
    
        this.name = name;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
    
    
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
    
    
        this.name = name;
    }
    
    public String toString() {
    
    
        return "Student{name = " + name + "}";
    }
}

/**
 * 具体原型类: Citation
 */
public class Citation implements Cloneable {
    
    
    private Student stu;

    public Student getStudent(){
    
    
        return stu;
    }

    public void setStudent(Student stu){
    
    
        this.stu = stu;
    }

    @Override
    public Citation clone() throws CloneNotSupportedException {
    
    
        return (Citation) super.clone();
    }

    public void show() {
    
    
        System.out.println(stu.getName() + "同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }
}

/**
 * 访问类: CitaionTest
 */
public class CitaionTest {
    
    
    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        // 创建原型对象
        Citation citation = new Citation();
        // 创建张三学生对象
        Student stu = new Student();
        stu.setName("张三");
        citation.setStudent(stu);
        // 克隆奖状对象
        Citation citation1 = citation.clone();
        Student stu1 = citation1.getStudent();
        stu1.setName("李四");

        //3,调用show方法展示
        citation.show();//李四同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!
        citation1.show();//李四同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!
    }
}

1.6.2 ディープクローン作成

新しいオブジェクトが作成されると、属性で参照されている他のオブジェクトも複製され、元のオブジェクトのアドレスを指さなくなります。ディープ クローン作成は、オブジェクト ストリームを使用して実装する必要があります

注: Citation クラスと Student クラスは Serializable インターフェイスを実装する必要があります。実装しない場合は NotSerializableException がスローされます。

/**
 * 学生实体类: Student
 */
public class Student implements Serializable {
    
    
    // 学生姓名
    private String name;

    public Student() {
    
    
    }

    public Student(String name) {
    
    
        this.name = name;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
    
    
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
    
    
        this.name = name;
    }
    
    public String toString() {
    
    
        return "Student{name = " + name + "}";
    }
}

/**
 * 具体原型类: Citation
 */
public class Citation implements Cloneable,Serializable {
    
    
    private Student stu;

    public Student getStudent(){
    
    
        return stu;
    }

    public void setStudent(Student stu){
    
    
        this.stu = stu;
    }

    @Override
    public Citation clone() throws CloneNotSupportedException {
    
    
        return (Citation) super.clone();
    }

    public void show() {
    
    
        System.out.println(stu.getName() + "同学:在2023学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }
}

/**
 * 访问类: CitaionTest
 */
public class CitaionTest {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 创建原型对象
        Citation citation = new Citation();
        // 创建张三学生对象
        Student stu = new Student();
        stu.setName("张三");
        citation.setStu(stu);

        // 创建对象输出流对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D://a.txt"));
        // 写对象
        oos.writeObject(citation);
        // 释放资源
        oos.close();

        // 创建对象输入流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D://a.txt"));
        // 读取对象
        Citation citation1 = (Citation) ois.readObject();
        // 释放资源
        ois.close();
        Student stu1 = citation1.getStu();
        stu1.setName("李四");

        citation.show();
        citation1.show();
    }
}

记录每一个学习瞬间

おすすめ

転載: blog.csdn.net/qq_51601665/article/details/131071684