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

news2024/12/25 15:15:27

目录

一、注解

内置注解: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;

    @Override
    protected 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;
    }

    @Override
    public 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() (重写了该方法)

    @Override
    protected 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;

    @Override
    protected 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;

    @Override
    protected 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{

    @Override
    public void run() {
        System.out.println("使用华为手机");
    }
}

iPhone手机运行

public class IPhone implements Phone{

    @Override
    public 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{
    @Override
    public void createPhone() {
        new HUAWEI();
    }
}

iPhone手机工厂

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

华为手机运行

public class HUAWEI implements Phone{

    @Override
    public void run() {
        System.out.println("使用华为手机");
    }
}

iPhone手机运行

public class IPhone implements Phone{

    @Override
    public 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{
    @Override
    public Car getCar() {
       return new RedmiCar();
    }

    @Override
    public Phone getPhone() {
        return new RedmiPhone();
    }
}

产品信息

public class RedmiPhone implements Phone{
    @Override
    public void call() {
        System.out.println("红米手机,年轻人的选择");
    }
}
public class RedmiCar implements Car{

    @Override
    public 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.coloradmin.cn/o/1402546.html

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

相关文章

【数据结构与算法】之字符串系列-20240122

这里写目录标题 一、383. 赎金信二、387. 字符串中的第一个唯一字符三、389. 找不同四、392. 判断子序列五、409. 最长回文串 一、383. 赎金信 简单 给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果…

【EI会议征稿通知】第五届电气、电子信息与通信工程国际学术会议 (EEICE 2024)

第五届电气、电子信息与通信工程国际学术会议 (EEICE 2024) 2024 5th International Conference on Electrical, Electronic Information and Communication Engineering (EEICE 2024) 第五届电气、电子信息与通信工程国际学术会议 (EEICE 2024)将于20…

消息中间件之RabbitMQ

1.RabbitMQ简介 1.基于AMQP协议Erlang语言开发的一款消息中间件,客户端语言支持比较多, 比如Python,Java,Ruby,PHP,JS,Swift.运维简单,灵活路由,但是性能不高, 可以满足一般场景下的业务需要,三高场景下吞吐量不高&am…

【SpringCloud Alibaba】 介绍及微服务模块搭建

文章目录 SpringCloud Alibaba 介绍主要功能组件 微服务环境搭建案例准备技术选型模块设计微服务调用 创建父工程创建基础模块1、创建 shop-common 模块2、创建实体类 创建用户微服务1、创建pom.xml2、编写主类3、创建配置文件 创建商品微服务1、创建一个名为 shop-product 的模…

机器学习实验报告——EM算法

目录 一、算法介绍 1.1算法背景 1.2算法引入 1.3算法假设 1.4算法原理 1.5算法步骤 二、算法公式推导 2.1数学基础 2.2EM算法推导 三、算法实现 3.1关于EM聚类 3.2EM工具包的使用 3.3 实例测试 四、算法讨论 4.1EM算法的优缺点 4.2EM算法的应用 4.3对于EM算法…

79、avx2 向量指令集优化卷积运算

上一节 介绍了 avx2 向量指令集中的 load/store 操作,本节介绍如何使用 avx2 的向量指令集来实现乘累加运算。 因为我们实战中用到的 resnet50 神经网络中,卷积运算在整个模型中的比例占据是相当高,而卷积运算的核心计算就是乘累加计算。因此,只要将最核心的乘累加计算效率…

【Linux】Shell 命令以及运行原理

Shell 命令以及运行原理 当用户登录 Linux 系统的时候,系统会给用户创建一个新的进程,一般叫做 bash(命令行解释器)。 Linux 严格意义上说的是一个操作系统,我们称之为 “核心( kernel )” &…

水利信息化监测平台 助力现代水利

​随着物联网、大数据、云计算等新技术在水利行业的广泛应用,水利信息化监测平台应运而生,在提升水利工程监测预警、增强水资源管理调度能力等方面发挥着重要作用。 一、水利信息化监测平台概述 水利信息化监测平台通过部署在水工程设施上的各类智能终端和传感器,形成信息采集…

MBR扇区修复和GRUB引导修复实验

修复MBR扇区 步骤一:在进行实验之前我们需要新加一块磁盘,并对新加磁盘进行分区处理,用来备份sda磁盘的MBR及分区表信息。(注:在实验中可以不像我如此这么繁琐,一个主分区,并格式化挂载即可&am…

亚像素边缘检测——基于模糊边缘模型的亚像素圆检测方法

论文:A Novel Subpixel Circle Detection Method Based on the Blurred Edge Model 期刊:IEEE Transactions on Instrumentation and Measurement, 71:1-11, 2021. 作者:Weihua Liu, Xianqiang Yang, Xuebo Yang, Hao Sun, Xinghu Yu, Huij…

无限商机、拓全国、赢未来!2024上海国际轴承展重磅来袭!

中国设备管理协会主办的“2024上海国际轴承及其专用装备展览会”将于2024年7月24日至26日在“国家会展中心(虹桥)”举办。展会预计展出面积55000平方米,汇聚来自世界各地的近1000家企业与60000多人次的国内外观众齐聚一堂。为期三天的展览会是…

计算机网络——运输层(2)暨小程送书

计算机网络——运输层(2)暨小程送书 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 运输层(2)TCP/IP对比TCP(传输控制协议):IP(互联网协议):总结 拥塞…

只会 Python 不行,不会 Python 万万不行 。。。

当下的环境大家有目共睹,未来一段时间情况如何,想必不少人心里也清楚,技术人走到中年,难免会焦虑,职场上干得不爽,但是跳槽也不容易,加上不少企业裁员,换个满意的工作更是难上加难。…

Python中r‘ ‘, b‘ ‘, u‘ ‘, f‘ ‘的含义及用法详解

更多资料获取 📚 个人网站:ipengtao.com 在Python中,字符串是一种常见的数据类型,用于表示文本信息。除了普通的字符串,Python还提供了一些特殊的字符串前缀和格式化字符串,包括r ,b ,u ,f 。本文将详细解…

windows用msvc编译opencv、opencv-python、opencv_contrib、cuda

如要用mingw编译opencv,参考我另外一篇文章https://blog.csdn.net/weixin_44733606/article/details/135741806。 如要用Ubuntu编译opencv,参考我另外一篇文章https://blog.csdn.net/weixin_44733606/article/details/131720128。 一、安装VS2022&…

数据操作——Column 对象

Column 对象 1. 什么是Column对象 Column 表示了 Dataset 中的一个列, 并且可以持有一个表达式, 这个表达式作用于每一条数据, 对每条数据都生成一个值 2.Column对象如何创建 ’ 单引号 ’ 在 Scala 中是一个特殊的符号, 通过 ’ 会生成一个 Symbol 对象, Symbol 对象可以理…

如何自己实现一个Spring Boot Starter

现在很多开源的组件都会提供对应的 springboot-starter 包给我们去用,要做一个 starter 包并不难。参照Spring内置的实现就好了: 1、在工程里引入 starter 打包相关的依赖。 2、在我们工程内建 spring.factories 文件,编写我们配置类的全限类…

ETLCloud:实现数据库快速输入输出的利器

在当今大数据时代,数据的高效处理和管理成为企业发展的关键。而数据库作为数据存储和管理的核心,其输入输出效率的提升对于企业来说至关重要。ETLCloud数据集成工具,为企业提供了快速、灵活、稳定的数据库输入输出解决方案,极大地…

最好的超声波清洗机有哪些?怎么样能选购到好用超声波清洗机?

眼镜党们在挑选超声波清洗机时候真的会非常苦恼,市面上的超声波清洗机品牌真的五花八门,让人挑得眼花缭乱,作为一个佩戴眼镜时间超达10年,使用超声波清洗机洗眼镜有五年的来说,我在选购超声波清洗机这条道路上吃的苦比…

线性代数:矩阵的定义

目录 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行(列)矩阵 七、同型矩阵 八、矩阵相等 九、零矩阵 十、方阵的行列式 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行(列)矩阵 七、同型矩…