原型模式的用法

news/2025/3/16 19:58:16/

文章目录

  • 一、原型模式的用法
    • 1.1 介绍
    • 1.2 结构
    • 1.3 原型模式类图
    • 1.4 实现
      • 1.4.1 克隆的分类
      • 1.4.2 代码
    • 1.5 "三好学生"奖状案例
      • 1.5.1 "三好学生"奖状类图
      • 1.5.2 代码
    • 1.6 深、浅克隆的区分
      • 1.6.1 浅克隆
      • 1.6.2 深克隆

一、原型模式的用法

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("具体的原型对象创建完成");}@Overridepublic Realizetype clone() throws CloneNotSupportedException {System.out.println("具体原型复制成功");// Object类中提供了clone()方法来实现浅克隆,强转为Realizetypereturn (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;}@Overridepublic 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属性值改为“李四”,两个Citation(奖状)对象中显示的都是李四。这就是浅克隆的效果,对具体原型类(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;}@Overridepublic 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;}@Overridepublic 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();}
}

记录每一个学习瞬间


http://www.ppmy.cn/news/243307.html

相关文章

【微机原理】8088/8086的寻址方式

目录 一.指令的组成 二.操作数的寻址方式 1.立即数寻址 2.寄存器寻址方式 3.存储器寻址方式 (1)直接寻址 (2)寄存器间接寻址 (3)寄存器相对寻址方式 (4)基址变址寻址方式&#xff08…

8086/8088 微机指令汇总

寻址方式 1.立即寻址仅适用于源操作数 2.间址寄存器仅可用BX BP(SS段) SI DI 3.SI DI 变址寄存器 BX BP基址寄存器 4.相对寻址:[BXDATA] [BX]DATA [BX]DATA 5.基址-变址相对寻址:5H[BX][SI] 6.隐含寻址:MUL BL 指令执行:ALB…

8086处理器

一、8086微处理器内部结构 8086CPU由两部分即指令执行部件( Execution Unit, EU)和总线接口部件(Bus Interface Unit, BIU) 组成,在图中用点画线隔开。指令执行部件主要由算术逻辑运算单元(ALU)、标志寄存器(FR)、 通用寄存器组和EU控制电路4个部件组成,…

8086CPU详解

一、8086CPU内部结构及工作过程 1.1 8086 CPU内部结构及工作过程 下面是 Intel 8086CPU 的介绍: (1) 16位微处理器; (2) 采用高速运算性能的 HMOS 工艺制造,芯片上集成了2.9万只晶体管; (3) 使用单一的 5V 电源,40 条…

8086/8088CPU内部结构

8086/8088的功能结构 8086和8088CPU按功能可分为两个独立的部分:总线接口单元BIU(Bus Interface Unit)和执行单元EU(Execution Unit) BIU: 完成CPU与存储器之间的信息传送总线控制IO数据传送逻辑地址与物理地址进行转换从存储器中取指令送至指令流队列排队取出执…

8086 CPU 寄存器

目录 概述 通用寄存器: 控制寄存器: 段寄存器: 通用寄存器 数据寄存器(AX,BX,CX,DX): 其他寄存器(CS,IP,SS,SP&…

8086cpu的寄存器

8086cpu的寄存器 文章目录 8086cpu的寄存器1.8086cpu寄存器的基本结构2.通用寄存器基础3.8086cpu给出物理地址的方法4.段寄存器剖析4.1 CS和IP寄存器4.2 DS和[address]寄存器4.3 SS和SP寄存器 1.8086cpu寄存器的基本结构 CPU由运算器、控制器、寄存器等器件构成,这些…

8086CPU

1、 8086CPU和8088CPU内部结构基本相同,不同之处在于8088有8条外部数据总线,因此为准16位。8086有16条外部数据总线。两个CPU的软件完全兼容,程序的编制也完全相同。 2、 8086CPU从功能上分为两大部分:一是执行部件&#xff08…