当前位置: 首页 > news >正文

java对象克隆和面向对象的设计原则

java进阶

    • 注解
      • 内置注解
      • 元注解
      • 自定义注解
    • 对象克隆
      • 浅克隆
      • 深克隆
    • java设计模式
      • 建模语言
        • 类之间的关系
        • 依赖关系
        • 关联关系
          • 单向关联
          • 双向关联
          • 自关联
        • 聚合关系
        • 组合关系
        • 继承关系
        • 实现关系
    • 面向对象设计原则
      • 单一职责
      • 开闭原则
      • 里氏替换原则
      • 依赖倒置
      • 接口隔离
      • 迪米特原则
      • 组合/聚合复用原则

注解

java注解又叫java标注,Java 语言中的类、方法、变量、参数和包等都可以被标注。

java注解,可以通过反射来获取注解内容,可以在编译期间使用,也可以被编译到字节码文件中,运行时生效.支持自定义注解

内置注解

java已经定义好的注解,比如

@Override:重写方法注解

@Deprecated:标记过时注解

@SuppressWarnings - 指示编译器去忽略注解中声明的警告。

@FunctionalInterface 用于指示被修饰的接口是函数式接口

元注解

元注解是由java API提供的,用于修饰注解,比如:

@Retention - 标识这个注解怎么保存,是只在代码中,还是编入 class 文件中,或者是在运行时可以通过反射访问。

@Documented - 标记这些注解是否包含在用户文档中。

@Target - 标记这个注解应该是哪种 Java 成员。

@Inherited - 标记这个注解是继承于哪个注解类(默认注解并没有继承于任何子类)

@Repeatable - 标识某注解可以在同一个声明上使用多次。

重点:@Target - 标记这个注解应该是哪种 Java 成员。

ElementType.TYPE 可以应用于类的任何元素。
ElementType.CONSTRUCTOR 可以应用于构造函数。
ElementType.FIELD 可以应用于字段或属性。
ElementType.LOCAL_VARIABLE 可以应用于局部变量。
ElementType.METHOD 可以应用于方法级注释。
ElementType.PACKAGE 可以应用于包声明。
ElementType.PARAMETER 可以应用于方法的参数

@Retention:@Retention 定义了该注解被保留的时间长短,用于注解的生命周期

1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在 class 文件中有效(即 class 保留)
3.RUNTIME:在运行时有效(即运行时保留)

自定义注解

1.自定义注解

@Target(ElementType.FIELD)//作用在类的属性上
@Retention(RetentionPolicy.RUNTIME)//运行时生效
public @interface NotNull {//定义注解属性String message() default "";int length() default 0;String lengthmessage() default "";
}

2.使用自定义注释

@NotNull(message="姓名不能为空",length=3,lengthmessage="长度不能小于3")private String name;

3.解析注释

             User user = new User();user.setName("jiim");//反射解析注解Field[] fields = user.getClass().getDeclaredFields();//获取所有的属性for (Field field : fields) {//获取属性的注解NotNull notNull = field.getAnnotation(NotNull.class);if (notNull != null) { Method m = user.getClass().getMethod("get" + getMethodName(field.getName()));Object value=m.invoke(user);//调用get方法 获取属性值//name值为空,抛出异常if (value==null) {System.err.println(field.getName() +notNull.message());throw new NullPointerException(notNull.message());}else{//判断name值的长度if(String.valueOf(value).length()<(notNull.length())){System.err.println(field.getName() +notNull.lengthmessage());}}}}

对象克隆

对象克隆是指创建一个新的对象,新的对象拥有之前对象内容。

如何是实现克隆

实现Cloneable接口,重写Object类中的clone方法就可以实现克隆,克隆分为浅克隆和深克隆,浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复值

浅克隆

浅克隆克隆值类型的成员变量克隆的是值,克隆引用类型的成员变量克隆的是对象地址。

   //重写clone方法@Overrideprotected Person clone() throws CloneNotSupportedException {Person person = (Person)super.clone();return person;}Person p1 = new Person(100,"jim");Person p2 =p1.clone();//克隆的新对象

实现方式:
1.在 Java 语言中,通过覆盖 Object 类的 clone()方法可以实现浅克隆。
2.在 spring 框架中提供 BeanUtils.copyProperties(source,target);
在这里插入图片描述

深克隆

深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。

实现方式:

  1. 类 实现Cloneable接口, 重写Object中的clone方法.(在多级关联时,处理起来比较麻烦)
//Address对象中重写clone方法
@Overrideprotected Address clone() throws CloneNotSupportedException {return (Address)super.clone();}//重写Person对象的clone方法@Overrideprotected Person clone() throws CloneNotSupportedException {Person person = (Person)super.clone();person.address = (Address)address.clone();   //深度复制  联同person中关联的对象也一同克隆.return person;}

2.使用序列化方式,可以重写创建对象,包含关联的对象。

/*** 自定义克隆方法* @return*/public Person myclone() {Person person = null;try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(this);// 将流序列化成对象ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);person = (Person) ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return person;}

在这里插入图片描述

解决多层克隆问题:我们可以用序列化的方式来实现对象的深克隆,来解决多层克隆的问题

java设计模式

软件设计模式,又称设计模式,它是被反复使用、代码设计经验的总结。它描述了在软件过程中重复发生的问题,以及该问题的解决方案。

设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。

优点:提高程序员的思维能力、编程能力和设计能力

​ 使程序设计更加标准化、提高软件开发效率

​ 设计的代码重用性高、可读性强、可维护性强

建模语言

统一建模语言(UML)是一种用于软件系统分析和设计的语言工具。

UML图:通过不同的图形和符号,来描述软件模型以及各个元素之间的关系

类图(Class diagram)是一种静态的结构图,描述了系统的类的集合,类的属性和类之间的关系。类图是系统分析和设计阶段的重要产物。

在这里插入图片描述

类之间的关系

在软件系统中,类不是孤立存在的,类与类之间存在各种关系。根据类与类之间的耦合度从弱到强排列,UML 中的类图有以下几种关系:依赖关系、关联关系、聚合关系、组合关系、泛化关系和实现关系。其中泛化和实现的耦合度相等,它们是最强的。

依赖关系

依赖关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。
在 UML 类图中,依赖关系使用带箭头的虚线来表示,箭头从使用类指向被依赖的类。下图所示是人与手机的关系图,人通过手机的语音传送方法打电话。

在这里插入图片描述

关联关系

关联关系是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系,如老师和学生、师傅和徒弟等。关联关系是类与类之间最常用的一种关系,分为一般关联关系、聚合关系和组合关系。

关联又可以分为单向关联,双向关联,自关联

单向关联

在这里插入图片描述

在 UML 类图中单向关联用一个带箭头的实线表示。上图表示每个顾客都有一个地址,这通过让 Customer 类持有一个类型为 Address

双向关联

在这里插入图片描述

从上图中我们很容易看出,所谓的双向关联就是双方各自持有对方类型的成员变量。上图中在 Customer 类
中维护一个 List,表示一个顾客可以购买多个商品;在 Product 类中维护一个 Customer 类型的成员变量表示这个产品被哪个顾客所购买

自关联

在这里插入图片描述

自关联在 UML 类图中用一个带有箭头且指向自身的线表示。上图的意思就是Node 类包含类型为 Node 的成员变量,也就是“自己包含自己”。

聚合关系

聚合关系是关联关系的一种,是强关联关系,是整体和部分之间的关系。聚合关系也是通过成员对象来实现的,其中成员对象是整体对象的一部分,但是成员对象可以脱离整体对象而独立存在。例如,学校与老师的关系,学校包含老师,但如果学校停办了,老师依然存在。

在这里插入图片描述

组合关系

组合表示类之间的整体与部分的关系,但它是一种更强烈的聚合关系。在组合关系中,整体对象可以控制部分对象的生命周期,一旦整体对象不存在,部分对象也将不存在,部分对象不能脱离整体对象而存在。例如,头和嘴的关系,没有了头,嘴也就不存在了
在这里插入图片描述

继承关系

继承关系是对象之间耦合度最大的一种关系,表示一般与特殊的关系,是父类与子类之间的关系,是一种继承关系,是 is-a 的关系

在这里插入图片描述

实现关系

实现关系是接口与实现类之间的关系。在这种关系中,类实现了接口,类中的操作实现了接口中所声明的所有的抽象操作。

在这里插入图片描述

面向对象设计原则

单一职责

单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小。简单来说,就是一个类只负责一个功能领域中的职责。

优点:低耦合、高内聚。

开闭原则

开闭原则即扩展开发,对修改封闭,简单来说就是在项目种增加新的业务功能时,不会修改原来的代码,而是通过增加类的方式来是实现新的业务功能。抽象化是开闭原则的关键。

在这里插入图片描述

优点:提高了可复用性可维护性

里氏替换原则

定义:所有使用父类的地方必须能透明地使用其子类对象,简单来说就是使用父类地地方子类也能使用。

所以遵循里氏替换原则时,子类继承父类时,不能重写父类的方法。

作用:是实现开闭原则的重要方式之一,克服了继承种重写父类方法造成的可复用性变差的缺点,降低需求变更时引入的风险。

依赖倒置

依赖倒置原则定义:上层模块不应该依赖底层模块,它们都应该依赖于抽象。简单来说就是要求对抽象进行编程,不要对实现进行编程。

在这里插入图片描述

接口隔离

使用多个接口,而不使用单一的总接口,不强迫新功能实现不需要的方法。

迪米特原则

迪米特原则又叫做最小知识原则,它要求一个对象应该对其他对象有最少的了解。只和你的直接朋友交谈。

直接朋友:

1.类中的成员属性

2.在类中的方法作为参数使用

3.在类中的方法作为返回值类型。

注意事项:

  • 迪米特法则的核心是降低类之间的耦合

  • 从被依赖者的角度来说,尽量将逻辑封装在类的内部,对外除了提供的public 方法,不泄露任何信息

  • 从依赖者的角度来说,只依赖应该依赖的对象

  • 切忌不要为了用而用

组合/聚合复用原则

优先使用组合,使系统更灵话,其次才考虑继承,达到复用的目的

使用继承,为了复用父类中的方法,但是类与类的耦合性高.可以使用关联/依赖,在一个类中达到复用别的类中的方法.

总结

  • 开闭原则:要求对扩展开放,对修改关闭
  • 里氏替换原则:不要破坏继承体系
  • 依赖倒置原则:要求面向接口编程
  • 单一职责原则:实现类职责要单一
  • 接口隔离原则:在设计接口的时候要精简单一
  • 迪米特法则:只与直接的朋友的通信
  • 组合/聚合原则:尽量使用聚合和组合的方式,而不是使用继承

设计原则的核心思想就是为了让程序高内聚,低耦合。

相关文章:

java对象克隆和面向对象的设计原则

java进阶注解内置注解元注解自定义注解对象克隆浅克隆深克隆java设计模式建模语言类之间的关系依赖关系关联关系单向关联双向关联自关联聚合关系组合关系继承关系实现关系面向对象设计原则单一职责开闭原则里氏替换原则依赖倒置接口隔离迪米特原则组合/聚合复用原则注解 java注…...

传透式血氧仪设计方案

该方案一种检测方式是选择使用光敏二极管接收光信号&#xff0c;采用传统穿透式夹指测量&#xff1b;另一种是使用光谱传感器接收光信号&#xff0c;采用反射式测量。该传感器可将光信号直接转换成数据信息给主控端进行处理&#xff0c;从而节省了用户将光信号转换成模拟信号&a…...

让逆向工程师们头疼的代码混淆,就像永远也走不出的“浪浪山”

目录 代码混淆究竟是什么&#xff1f; 如何做代码混淆&#xff1f; 代码混淆不等于加密 App 加固非一时之功 “我想离开浪浪山。” 在数次尝试破解某个App 时&#xff0c;某个逆向工程师无奈感慨道。 逆向工程师顾名思义就是把一个个完整的软件逆推&#xff0c;还原成一段段…...

【拓展】基于机器学习的心脏病预测方法(14)——心脏病数据集补充

目录 前言1、数据集11.1 数据集介绍1.2 数据集属性2、数据集22.1 数据集介绍2.2 数据集属性3、数据集33.1 数据集介绍3.2 数据集属性4、下载地址前言 在实际研究过程中,前文所述数据集由于尺寸过小(仅有303份数据和13个属性信息)或数据集单一(仅有一个数据集,不具备普适性…...

深度解读Webpack中的loader原理

一、前言 webpack 是一个现代 JavaScript 应用的静态模块打包器。那么 webpack 是怎样实现不同种类资源模块加载的呢&#xff1f; 没错就是通过 loader。loader 用于对模块的源代码进行转换。loader 可以使你在 import 或加载模块时预处理文件。 我们带着下面几个问题&#…...

2023年全国最新二级建造师精选真题及答案

百分百题库提供二级建造师考试试题、二建考试预测题、二级建造师考试真题、二建证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 一、单选题 1.关于法人在建设工程中的地位的说法&#xff0c;正确的是&#xff08;&#xff0…...

为什么现代企业发展离不开CRM系统的助力

如今的CRM系统对于任何企业来说都重要&#xff0c;因为它能帮助企业收获新客户&#xff0c;保留现有客户&#xff0c;并且将不同部门的信息全部汇集&#xff0c;实时提供关于每位客户整体全面的看法。因此&#xff0c;销售、市场营销和客户支持等领域的客户直接服务员工能够做出…...

vb.net计算之.net core基础(1)-获取农历和天气

目录 .net core 简介创建hello,world应用程序获取天气和农历.net core 简介 .NET Core是适用于 Windows、Linux 和 macOS 的免费、开源托管的计算机软件框架。 它是微软开发的第一个官方版本,具有跨平台能力的应用程序开发框架 (Application Framework),未来也将会支持 Free…...

设计模式之代理模式详解和应用

目录1 代理模式定义2 代理模式的应用场景3 代理模式的通用写法4 从静态代理到动态代理5 静态模式在业务中的应用6 动态代理在业务中的应用7 手写JDK动态代理实现原理7.1 JDK动态代理的实现原理7.2 CGLib动态代理容易踩的坑8 CGLib代理调用API及原理分析9 CGLib和JDK动态代理对比…...

JavaScript HTML DOM 节点列表

HTML DOM 是一种文档对象模型&#xff0c;它允许开发人员使用 JavaScript 来访问和修改网页的内容和结构。节点列表是 HTML DOM 中一个重要的概念&#xff0c;它允许开发人员以编程方式访问和操作文档中的节点元素。 在本文中&#xff0c;我们将探讨 JavaScript HTML DOM 节点…...

【音视频处理】码率、帧率越高越清晰?分辨率、像素、dpi之间是什么关系?码率的真实作用,I帧、B帧、P帧是什么

大家好&#xff0c;欢迎来到停止重构的频道。本期我们介绍一下视频的一些基础概念&#xff0c;如帧率、码率、分辨率、像素、dpi、视频帧、I帧、P帧、gop等。会解释多少码率是清晰的&#xff0c;是否帧率越高越流畅等问题。这些概念是比较杂乱的&#xff0c;我们按这样的顺序介…...

Java基础-认识注释、标识符关键字

注释 平时我们编写代码&#xff0c;当代码量较小时候&#xff0c;我们还可以看懂自己写的代码。但是当项目结构一旦复杂起来&#xff0c;我们就需要用到注释啦。注释并不会被执行&#xff0c;是写给我们开发者看的。 在java中的注释有三种 标识符 常见关键字 Java所有的组…...

【C#】静态扩展方法

静态类特征:1.不能用sealed或abstract修饰符&#xff1b;2.必须直接继承System.Object类型&#xff0c;不能试任何其他类的派生类&#xff1b;3.不能实现任何接口&#xff1b;4.不能包含任何操作符&#xff1b;5.不能使用protected或者protected internal修饰的静态成员&#x…...

医疗电子方案——血压计方案

高血压人群越来越多了&#xff0c;尤其是老人。高血压是一种十分常见的慢性疾病&#xff0c;同时也是引发心血管疾病最主要的因素。有关数据表明&#xff0c;我国每年因高血压死亡的病例竟然达到上百万之多&#xff0c;占到全部死亡比例的20%以上。所以大多数家庭都需要备有家用…...

深度分析React源码中的合成事件

热身准备 明确几个概念 在React17.0.3版本中&#xff1a; 所有事件都是委托在id root的DOM元素中&#xff08;网上很多说是在document中&#xff0c;17版本不是了&#xff09;&#xff1b;在应用中所有节点的事件监听其实都是在id root的DOM元素中触发&#xff1b;React自…...

17.微服务SpringCloud

一、基本概念 Spring Cloud 被称为构建分布式微服务系统的“全家桶”&#xff0c;它并不是某一门技术&#xff0c;而是一系列微服务解决方案或框架的有序集合。它将市面上成熟的、经过验证的微服务框架整合起来&#xff0c;并通过 Spring Boot 的思想进行再封装&#xff0c;屏蔽…...

Java基础面试题——JavaWeb专题

文章目录1.HTTP响应码有哪些2.Forward和Redirect的区别&#xff1f;3.Get和Post请求的区别4.介绍下OSI七层和TCP/IP四层的关系5.说说TCP和UDP的区别6. 说下HTTP和HTTPS的区别7.说下HTTP、TCP、Socket的关系是什么&#xff1f;8. 说下HTTP的长链接和短连接的区别9.TCP原理10. Co…...

MySql数据库约束

概述、目的 概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 目的&#xff1a;保证数据库中数据的正确性、有效性和完整性。 分类&#xff1a; 约束描述关键字非空约束限制该字段的数据不能为nullNOT NULL唯一约束保证该字段的所有数据都…...

TripleCross:一款功能强大的Linux eBPF安全研究工具

关于TripleCross TripleCross是一款功能强大的Linux eBPF安全研究工具&#xff0c;该工具提供了后门、C2、代码库注入、执行劫持、持久化和隐蔽执行等功能。 功能介绍 1、使用一个代码库注入模块通过往进程的虚拟内存中写入命令来执行恶意代码&#xff1b; 2、提供了一个行劫…...

2023最牛教程,手把手教你成为年薪30W的测试开发

随着互联网行业的高速发展&#xff0c;快速高质量的产品版本迭代成为企业始终立于不败之地的迫切需求&#xff0c;而在短期迭代的快节奏中&#xff0c;传统测试工作面对更大压力&#xff0c;无法持续提供高效率高质量的人力支撑&#xff0c;所以越来越多的企业需要技术更为全面…...

“深度学习”学习日记。--ImageNet、VGG、ResNet

2023.2.14 一、小历史&#xff1a; 在2012年的ILSVRC(ImageNet Large Scale Visual Recognitoin Chanllege)&#xff0c;基于深度学习的方法AlexNet 以绝对优势获胜并且他颠覆了以前的图片识别方法&#xff0c;此后深度学习方法一直活跃在这个舞台。 二、ImageNet&#xff1…...

关于APP下载量提升的技巧

关于APP应用下载量提升&#xff0c;很多人都不是很了解。今天厦门巨神峰小编给大家说下关于APP下载量提升的几个技巧。 一、抓住流行趋势&#xff0c;提升APP下载量 1、利用社交媒体进行推广。社交媒体是当下最流行的推广手段&#xff0c;可以有效的将APP的消息传播到更多的用…...

以“大数据”赋能产业链精准招商

​ 随着我国产业发展的不断迭代升级&#xff0c;传统招商模式的不足逐步凸显&#xff0c;侧重土地与税费优惠的同质化竞争招商以及来者不拒的无门槛型招商已经遏制了区域产业的发展&#xff0c;导致各产业园区很难形成产业集聚及持续的吸引力。在这样的大环境下&#xff0c;产业…...

内存泄漏检测组件 -- hook

目录 hook malloc与free出现的问题 builtin_return_address(N) C/CLinux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂 hook malloc与free出现的问题 #define _GNU_SOURCE #include <stdio.h> #include <dlfcn.h> #include <stdlib.h> /****…...

Diffusion model(三): 公式结论

接上文 Diffusion model(一): 公式推导详解 这一节主要总结之前文章的公式结论 1. 已知x0x_{0}x0​时&#xff0c;sample过程的均值和方差 q(xt−1∣xt,x0)(xt−1;μ~(xt,x0),β~tI)\begin{aligned} q(x_{t-1}|x_{t}, x_{0}) \mathcal(x_{t-1}; \tilde{\mu}(x_{t}, x_{0}),…...

Angular笔记(二)组件

组件包括&#xff1a; HTML 模板: 声明页面渲染的内容TypeScript 类: 定义行为CSS 选择器: 定义组件在模板中的使用方式&#xff08;可选&#xff09;要应用在模板上的 CSS 样式 一、 创建组件: 使用 Angular CLI 创建一个组件 ng generate component <component-name>…...

微信小程序|基于小程序+C#制作一个超酷的个人简历

你还在用以前的方式投简历吗?趁着金三银四来临之际,跟随此文使用小程序制作一个便携超酷的个人简历,高调炫技,愉快的收offer吧! 一、小程序...

华为OD机试 - 最快到达医院的方法(Java JS Python)

题目描述 新型冠状病毒疫情的肆虐,使得家在武汉的大壮不得不思考自己家和附近定点医院的具体情况。 经过一番调查,大壮明白了距离自己家最近的定点医院有两家。其中: 医院A和自己的距离是X公里医院B和自己的距离是Y公里由于武汉封城,公交停运,私家车不能上路,交通十分不…...

92.【SpringCloud NetFilx】

SpringCloud(一)、这个阶段该如何学习?1.微服务介绍2.面试常见问题(二)、微服务概述1.什么是微服务?2. 微服务与微服务架构(1).微服务(2).微服务架构⭐(3). 微服务优缺点(4). 微服务技术栈有那些&#xff1f;(5). 为什么选择SpringCloud作为微服务架构(三)、SpringCloud入门概…...

[ahk]如何载入Scite的会话Session文件

加载session文件的AutoHotkey代码&#xff1a;oSciTE : ComObjActive("SciTE4AHK.Application") messageloadsession:d:\\ddd\\2023-2-15SciTE.session oSciTE.SendDirectorMsg(message)存储session文件的AutoHotkey代码&#xff1a;messagesavesession:d:\\ddd\\123…...