JAVASE进阶(设计模式、设计原则)(更新中...)

目录

一、注解

内置注解:JAVA中已经定义好的注解。

元注解:修饰注解的注解。

自定义注解。

二、克隆 

JAVA中对clone的实现?

浅克隆

深克隆

 那么该如何做到深克隆呢?

三、常用设计模式

        1、创建型模式

        单例模式

        工厂模式

        工厂方法模式 

        抽象工厂模式

        原型模式


一、注解

java中的注解也称标注,可以用来对类、方法、属性、参数、包等进行标注。然后让编译器或运行时其他类进行解析。完成某个功能注解也可以编译到字节码文件中。

内置注解:JAVA中已经定义好的注解。
@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接
口中并没有该方法时,会报编译错误。
@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
@SuppressWarnings - 指示编译器去忽略注解中声明的警告。
@FunctionalInterface 用于指示被修饰的接口是函数式接口。
元注解:修饰注解的注解。
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入 class 文件中,
或者是在运行时可以通过反射访问。
@Documented - 标记这些注解是否包含在用户文档中。
@Target - 标记这个注解应该是哪种 Java 成员。
@Inherited - 标记这个注解是继承于哪个注解类(默认注解并没有继承于任何
子类)
@Repeatable - 标识某注解可以在同一个声明上使用多次。
自定义注解。

二、克隆 

克隆分为浅克隆、深克隆。

JAVA中对clone的实现?

①实现Cloneable接口

②重写clone方法(Object类中的方法)

浅克隆

克隆一个对象时,如果对象中有关联关系(has-a,把一个类当作另一个类的属性),只将关联对象的地址复制过来(只拿地址)

举例:

public class CloneDemo {public static void main(String[] args) throws CloneNotSupportedException {Student s1=new Student();Address address=new Address();address.setAddress("江苏");s1.setName("Mike");s1.setAge(20);s1.setAddress(address);Student s2=s1.clone();s2.setAge(21);s2.setName("Amy");address.setAddress("陕西");s2.setAddress(address);System.out.println(s1);System.out.println(s2);}
}
public class Student implements Cloneable{int age;String name;Address address;@Overrideprotected Student clone() throws CloneNotSupportedException {return (Student) super.clone();}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}@Overridepublic String toString() {return "Student{" +"age=" + age +", name='" + name + '\'' +", address=" + address.address +'}';}
}

public class Address {String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}

运行结果

这是一个浅克隆的例子, 主函数中定义了一个叫Mike的Student对象实例,Student类中有基本类型age和name,还有引用类型Address。我们在主函数中使用了Object类中的方法clone() (重写了该方法)

    @Overrideprotected Student clone() throws CloneNotSupportedException {return (Student) super.clone();}

从运行结果发现基本数据类型修改不影响被克隆的对象,但是关联对象数据被修改,克隆的和被克隆的对象都被修改了。可以证明 浅克隆的定义:克隆一个对象时,如果对象中有关联关系(has-a,把一个类当作另一个类的属性),只将关联对象的地址复制过来(只拿地址)

所以浅克隆支持引用类型成员变量的复制 

并且我们发现,克隆的对象和被克隆的对象的地址不同,即使用clone()方法 会创建一个新对象,这里区别于JAVA中的引用

深克隆

克隆一个对象时,如果对象中有关联关系,将关联对象一同克隆(创建一个新的关联对象)

 那么该如何做到深克隆呢?

1、连同关联对象一同克隆,逐级克隆(层级过多会比较麻烦)

public class CloneDemo {public static void main(String[] args) throws CloneNotSupportedException {Student s1=new Student();Address address=new Address();address.setAddress("江苏");s1.setName("Mike");s1.setAge(20);s1.setAddress(address);Student s2=s1.clone();s2.setAge(21);s2.setName("Amy");address.setAddress("陕西");System.out.println(s1);//Mike 20 陕西System.out.println(s2);//Amy 21 江苏}
}
public class Student implements Cloneable{int age;String name;Address address;@Overrideprotected Student clone() throws CloneNotSupportedException {Student s=(Student) super.clone();Address address=(Address)s.getAddress().clone();s.setAddress(address);return s;}
}
public class Address implements Cloneable{String address;@Overrideprotected Address clone() throws CloneNotSupportedException {return (Address) super.clone();}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}

 在Student类中再使用clone()方法克隆Address对象,并且在Address类中重写clone()方法。

运行结果

通过结果发现,改变了关联对象地址,克隆对象的地址并未改变,说明深克隆不支持引用类型成员变量的复制。 

2、序列化(对象的输入输出流)

三、常用设计模式

        1、创建型模式

         用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使 用分离”。提供了单例、原型、工厂方法、抽象工厂、建造者 5 种创建型模式。

        单例模式

        在有些系统中,为了节省内存资源、保证数据内容的一致性,对某些类要求 只能创建一个实例,这就是所谓的单例模式. 例如,Windows 中只能打开一个 任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费, 或出现各个窗口显示内容的不一致等错误。单例模式有 3 个特点: 1. 单例类只有一个实例对象; 2. 该单例对象必须由单例类自行创建; 3. 单例类对外提供一个访问该单例的全局访问点;

        工厂模式

1、简单工厂:有一个工厂类负责生产某一类产品,同一类产品具备同一个抽象父类(抽象类/接口)。将创建对象与使用对象分离(Spring框架的设计思想)。简单工厂违背了开闭原则,添加一个产品就需要修改代码。子类过多,会导致工厂类庞大

以手机工厂为例:

手机接口:

public interface Phone {public  void run();
}

手机工厂接口:

public interface PhoneFactory {void createPhone();
}

有两种品牌的手机:HUAWEI和IPhone

手机工厂,重写创建手机方法

public class PhoneFactory {static Phone createPhone(String name) {if (name.equals("HUAWEI")) {return (Phone) new HUAWEI();}else if(name.equals("IPhone")){return (Phone) new IPhone();}else {return null;}}
}

华为手机运行

public class HUAWEI implements Phone{@Overridepublic void run() {System.out.println("使用华为手机");}
}

iPhone手机运行

public class IPhone implements Phone{@Overridepublic void run() {System.out.println("使用苹果手机");}
}

主函数

public class Solution {public static void main(String[] args) {PhoneFactory huaweiFactory=new HUAWEIFactory();Phone huaweiPhone=new HUAWEI();huaweiPhone.run();PhoneFactory iphoneFactory=new IPhoneFactory();Phone iphonePhone=new IPhone();iphonePhone.run();}
}

运行结果:

        工厂方法模式 

对工厂进行抽象,一个抽象的产品对应一个抽象的工厂。一个具体的产品对应一个具体的工厂,一个具体的工厂负责生产一个具体的产品,需要扩展新产品时,只需要添加新的具体的产品类,和新的生产该产品的工厂类即可。这样就不需要修改原来的工厂,符合开闭原则。

手机接口:

public interface Phone {public  void run();
}

手机工厂接口:

public interface PhoneFactory {void createPhone();
}

有两种品牌的手机:HUAWEI和IPhone

HUAWEI手机工厂

public class HUAWEIFactory implements PhoneFactory{@Overridepublic void createPhone() {new HUAWEI();}
}

iPhone手机工厂

public class IPhoneFactory implements PhoneFactory{@Overridepublic void createPhone() {new IPhone();}
}

华为手机运行

public class HUAWEI implements Phone{@Overridepublic void run() {System.out.println("使用华为手机");}
}

iPhone手机运行

public class IPhone implements Phone{@Overridepublic void run() {System.out.println("使用苹果手机");}
}

主函数

public class Solution {public static void main(String[] args) {PhoneFactory huaweiFactory=new HUAWEIFactory();Phone huaweiPhone=new HUAWEI();huaweiPhone.run();PhoneFactory iphoneFactory=new IPhoneFactory();Phone iphonePhone=new IPhone();iphonePhone.run();}
}

运行结果:

        抽象工厂模式

抽象工厂时生产一系列产品(某公司的产品华为手机,华为汽车),在抽象工厂中定义生产不同的产品,具体工厂负责生产一个公司的一系列产品

 定义一个抽象工厂

public interface AbstractFactory {Car getCar();Phone getPhone();
}

定义 汽车接口,手机接口

public interface Phone {void call();
}

public interface Car {void run();
}

定义产品工厂

public class RedmiFactory implements AbstractFactory{@Overridepublic Car getCar() {return new RedmiCar();}@Overridepublic Phone getPhone() {return new RedmiPhone();}
}

产品信息

public class RedmiPhone implements Phone{@Overridepublic void call() {System.out.println("红米手机,年轻人的选择");}
}
public class RedmiCar implements Car{@Overridepublic void run() {System.out.println("米家汽车,安心可靠");}
}

 主函数

public class Solution {public static void main(String[] args) {AbstractFactory redmiFactory=new RedmiFactory();Car redmiCar=redmiFactory.getCar();Phone redmiPhone= redmiFactory.getPhone();redmiCar.run();redmiPhone.call();}
}

运行结果

        原型模式

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能(new一个对象非常昂贵)。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/641378.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【GitHub项目推荐--一个语音机器人项目】【转载】

推荐一个腾讯大佬开源的语音对话机器人:wukong-robot ,悟空机器人在 GitHub 上斩获 3.2K 的 Star。 这是一个简单灵活的中文语音对话机器人项目,目的是让中国的开发者也能快速打造个性化的智能音箱,同时,该项目还是第…

QTableWidget 双击单元格修改数据

本章介绍通过双击单元格,进入单元格,进行编辑,并对比是否修改了数据,如果修改了更新到数据库。 其他关于QTableWidget的操作,请查看上一篇文章《QTableWidget 用法-CSDN博客》 修改单元格内容,与原值比较…

vue3 npm i 一直卡到不动

一. 首先node 版本要18.0及以上 查看node版本并安装指定版本 二. 查看npm镜像源以及指定安装npm的镜像 三. 删除项目中的package-lock.json文件 最好是把node_modules安装包也删除掉,然后npm i 就可以了

配置jdk环境变量

查看jdk在什么地方的命令 echo $JAVA_HOME 查看jdk的执行路径--使用which java whereis java zip -qr jdk21.zip jdk21/ 手动配置Java环境变量 修改配置环境 vim /etc/profile 把下面的配置放到文件的最后一行 export JAVA_HOME/usr/local/jdk1.8.0_202 # 这里设置…

网络安全人员一定要知道的Metasploit渗透框架!

简介 Metasploit是一款开源安全漏洞检测工具,附带数百个已知的软件漏洞,并保持频繁更新。被安全社区冠以“可以黑掉整个宇宙”之名的强大渗透测试框架。 Metasploit官网:www.metasploit.com/ Metasploit的Github仓库地址:githu…

时间序列预测 — CNN-LSTM-Attention实现多变量负荷预测(Tensorflow):多变量滚动

专栏链接:https://blog.csdn.net/qq_41921826/category_12495091.html 专栏内容 ​ 所有文章提供源代码、数据集、效果可视化 ​ 文章多次上领域内容榜、每日必看榜单、全站综合热榜 ​ ​ ​ ​ ​ ​ ​ 时间序列预测存在的问题 ​ 现有的大量方法没有真正的预测未…

【目标检测】YOLOv7算法实现(二):正样本匹配(SimOTA)与损失计算

本系列文章记录本人硕士阶段YOLO系列目标检测算法自学及其代码实现的过程。其中算法具体实现借鉴于ultralytics YOLO源码Github,删减了源码中部分内容,满足个人科研需求。   本篇文章在YOLOv5算法实现的基础上,进一步完成YOLOv7算法的实现。…

40尺货柜可以装载多少张建筑模板?

在建筑行业,40尺货柜一直以其标准化、便捷的特点成为建材运输的首选。然而,对于建筑模板这样的大型且薄型货物,如何在40尺货柜中实现最高效的装载一直是一项具有挑战性的任务。让我们一起揭秘,40尺货柜究竟能够装载多少张建筑模板…

上门回收小程序,打造回收新模式

近年来,我国一直秉持着环保绿色的发展理念,为了减少资源浪费,旧物回收成为了人们处理废弃物品的方式。目前,我国回收市场规模大约能达到3.58亿元,在我国经济的稳定增长和环保意识的提高下,回收市场规模还将…

科技、文化与旅游的融合创新:智慧文旅的未来之路

在当今社会,科技、文化与旅游的融合已经成为文旅产业转型升级的重要趋势。这种融合不仅有助于提升文旅产业的核心竞争力,更有助于推动产业的数字化转型和可持续发展。 本文将深入探讨科技、文化与旅游的融合创新,以及智慧文旅场景的解决方案…

【C++语言1】基本语法

前言 💓作者简介: 加油,旭杏,目前大二,正在学习C,数据结构等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏&#x1…

代码+视频R语言绘制逆概率加权后的基线表

基于 PS (倾向评分)的逆概率加权(IPTW )法首先由Rosenbaum作为一种以模型为基础的直接标准化法提出,属于边际结构模型。简单来说,就是把许多协变量和混杂因素打包成一个概率并进行加权,这样的话&#xff0c…

【GoLang入门教程】Go语言工程结构详述

程序员裁员潮:技术变革下的职业危机 文章目录 程序员裁员潮:技术变革下的职业危机前言总结:专栏集锦强烈推荐写在最后 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网…

3d音响按键怎么建立模型---模大狮模型网

要建立3D音响按键的模型,您可以按照以下步骤进行: 选择建模软件:首先,选择一个三维建模软件,如Blender、3ds Max或Maya。这些软件都提供了丰富的建模工具和功能,适合用于创建复杂的三维模型。 参考图像&am…

java SSM自助快递服务平台myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM自助快递服务平台是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代 码和数据库,系统主要采…

DophineScheduler通俗版

1.DophineScheduler的架构 ZooKeeper: AlertServer: UI: ApiServer: 一个租户下可以有多个用户;一个用户可以有多个项目一个项目可以有多个工作流定义,每个工作流定义只属于一个项目;一个租户可…

人工智能原理实验4(2)——贝叶斯、决策求解汽车评估数据集

🧡🧡实验内容🧡🧡 汽车数据集 车子具有 buying,maint,doors,persons,lug_boot and safety六种属性,而车子的好坏分为uncc,ucc,good and vgood四种。 🧡🧡贝叶斯求解🧡🧡…

Redis——RDB持久化

前言 Redis是一个键值对数据库服务器,服务器中通常包含任意个非空数据库,而每个非空数据库中又可以包含任意个键值对,为了方便起见,我们将服务器中的非空数据库以及它们的键值对统称为数据库状态。 因为Redis数据库是内存数据库&a…

Java/Python/Go不同开发语言在进程、线程和协程的设计差异

Java/Python/Go不同开发语言在进程、线程和协程的设计差异 1. 进程、线程和协程上的差异1.1 进程、线程、协程的定义1.2 进程、线程、协程的差异1.3 进程、线程、协程的内存成本1.4 进程、线程、协程的切换成本 2. 线程、协程之间的通信和协作方式2.1 python如何实现线程通信&a…

大模型实战营Day6 笔记

本期主题为: 为何测评,因场景众多,需要统一的标准: 评测的意义: 传统NLP的一些评测需要: 到了大模型时代,需要评测的就更多了: 客观评测: 有些主观题可以用模型评价…