Java基础:面向对象编程7

1 Java 不可变对象

1.1 什么是不可变类

  • 定义:一个类的对象在通过构造方法创建后,其状态(成员变量值)不会再被改变,这样的类称为不可变(immutable)类。
  • 特点
    • 所有成员变量的赋值仅在构造方法中完成。
    • 不提供任何 setter 方法供外部类修改成员变量。
  • 优点
    • 对象状态不可变,每次修改状态都会产生新对象,避免并发问题。

1.2 常见的不可变类

  • String 类
    • 常量池:字符串常量池是 Java 堆内存中一个特殊的存储区域,当创建一个 String 对象时,假如此字符串在常量池中不存在,那么就创建一个;假如已经存在,就不会再创建了,而是直接引用已经存在的对象。这样做能够减少 JVM 的内存开销,提高效率。
    • hashCode:因为字符串是不可变的,所以在它创建的时候,其 hashCode 就被缓存了,因此非常适合作为哈希值(比如作为HashMap的键),多次调用只返回同一个值,来提高效率。
    • 线程安全:如果对象的状态是可变的,那么在多线程环境下,就很容易造成不可预期的结果。而 String 是不可变的,就可以在多个线程之间共享,不需要同步处理。
    • 方法返回新对象:当我们调用 String 类的任何方法(比如说 trim()、substring()、toLowerCase())时,总会返回一个新的对象,而不影响之前的值。
  • 包装类
    • 除了 String 类,包装器类 Integer、Long 等也是不可变类

1.3 手撸一个不可变类

1.3.1 条件

  1. 类声明为 final:防止子类修改。
  2. 成员变量声明为 final:确保初始化后不可更改。
  3. 不提供 setter 方法:防止外部修改状态。
  4. 修改状态返回新对象:例如,String 的 substring() 方法。

1.3.2 代码示例

  • 来自定义一个简单的不可变类 Writer
/**
 * @package: com.yunyang.javabetter.oop.immutabledemo
 * @description: 定义一个简单的不可变类 Writer
 * @author: Yunyang
 * @date: 2024/10/16  9:21
 * @version:1.0
 **/
public final class Writer {
    private final String name;
    private  final int age;
    private final Book book;

    public Writer(String name, int age, Book book) {
        this.name = name;
        this.age = age;
        this.book = book;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Book getBook() {
        Book clone = new Book();
        clone.setPrice(this.book.getPrice());
        clone.setName(this.book.getName());
        return clone;
    }
}

Writer 类是 final 的,name、age 和 book 也是 final 的,没有 setter 方法

  • Book 类是这样定义的
/**
 * @package: com.yunyang.javabetter.oop.immutabledemo
 * @description: Book类
 * @author: Yunyang
 * @date: 2024/10/16  9:23
 * @version:1.0
 **/
public class Book {
    private String name;
    private int price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

2 个字段,分别是 name 和 price,以及 getter 和 setter,重写后的 toString() 方法

  • 测试类
/**
 * @package: com.yunyang.javabetter.oop.immutabledemo
 * @description: 测试类
 * @author: Yunyang
 * @date: 2024/10/16  9:26
 * @version:1.0
 **/
public class WriteDemo {
    public static void main(String[] args) {
        Book book = new Book();
        book.setName("Java进阶之路");
        book.setPrice(79);

        Writer writer = new Writer("沉默王二", 18, book);
        System.out.println("定价: " + writer.getBook());
        writer.getBook().setPrice(59);
        System.out.println("促销价:" + writer.getBook());
    }
  • 注意:如果一个不可变类中包含了可变类的对象,那么就需要确保返回的是可变对象的副本。所以,Writer 类中的 getBook() 方法被修改为:
public Book getBook() {
    Book clone = new Book();
    clone.setPrice(this.book.getPrice());
    clone.setName(this.book.getName());
    return clone;
}
  • 运行结果:
定价: Book{name='Java进阶之路', price=79}
促销价:Book{name='Java进阶之路', price=79}

1.4 小结

不可变对象是 Java 中一种重要的设计模式,能够提高代码的安全性、可维护性和性能。掌握不可变类的概念和设计原则,对于编写高质量的 Java 代码至关重要。

2 Java 方法重写和方法重载

2.1 引入

方法重载

  • 定义:一个类中可以有多个名字相同但参数个数或类型不同的方法。
  • 目的:提高程序的可读性,避免为相似功能的方法取不同的名字。

方法重写

  • 定义:子类中定义与父类相同的方法(方法名、参数、返回类型相同,但方法体可能不同)。
  • 目的:提供父类方法的特殊实现,实现多态。

2.2 方法重载

实现方式

  1. 改变参数数目:例如,add(int a, int b)add(int a, int b, int c)
  2. 改变参数类型:例如,add(int a, int b)add(double a, double b)

重载 main 方法

  • 尽管可以重载 main() 方法,但程序只认标准写法 public static void main(String[] args)

重载与类型转换

  • 当传递的参数类型不匹配时,会发生隐式类型转换。
  • 例如,byte 可以转换为 shortintlongfloatdouble

2.3 方法重写

规则

  1. 方法名相同
  2. 参数相同
  3. 继承关系(is-a 关系)。

重写时应当遵守的规则

  1. 只能重写继承的方法:只能重写 publicprotecteddefault 修饰的方法,private 方法无法被重写。
  2. final、static 方法不能被重写
    • final 方法无法被子类继承,因此无法重写。
    • static 方法属于类,而不是对象,因此无法重写。
  3. 参数列表必须相同
  4. 返回类型必须相同
  5. 权限修饰符不能更严格
    • default 方法可以重写为 defaultprotectedpublic
    • protected 方法可以重写为 protectedpublic
    • public 方法只能重写为 public
  6. 不能抛出更高级别的异常:只能抛出父类方法抛出异常的子类或不抛出异常。
  7. 使用 super 调用父类方法
  8. 构造方法不能被重写:构造方法与类名相同,子类无法重写父类的构造方法。
  9. 抽象方法必须在子类中重写
  10. synchronized 不影响重写规则synchronized 关键字用于多线程环境,不影响重写规则。
  11. strictfp 不影响重写规则strictfp 关键字用于精确浮点运算,不影响重写规则。

2.4 小结

方法重载

  • 两同:在同一个类,方法名相同。
  • 一不同:参数不同。

方法重写

  • 两同:方法名相同,参数相同。
  • 一小:子类方法声明的异常类型要比父类小或相等。
  • 一大:子类方法的访问权限要比父类大或相等。

3 思维导图

在这里插入图片描述
在这里插入图片描述

4 参考链接

  1. 聊聊Java中的不可变对象
  2. 方法重写 Override 和方法重载 Overload 有什么区别

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

生成 Excel 表列名称

Excel 大家都用过,它的列名是用字母编号的,A 表示第一列,B 表示第二列,AA 表示第27列,AB 表示第28列等等。 现给定一个数字,如何得到列名称呢。比如输入28,输出 AB。 一开始以为就是一个简单的…

2017年计算机网络408真题解析

第一题: 解析:OSI体系结构数据包的逐层封装 应用层发送的400B数据称为应用层协议数据单元,也就是题目所说的PDU, 表示层将应用层发过来的PDU添加一个20B的首部,封装称为表示层PDU,并将其交付给会话层&#…

接口测试(一)基础

一、http请求格式 请求&#xff1a;从客户端到服务端的请求消息 请求消息格式 请求行&#xff1a;请求方法、请求URL、HTTP协议及版本 URL的一般形式为<协议>://<主机>:<端口>/<路径>/<文件名>请求头部空一行请求体 请求方法 请求方法get请求…

HCIP——以太网交换安全(四)DHCP Snooping

目录 一、DHCP Snooping的知识点 二、DHCP Snooping实验拓扑 三、总结 一、DHCP Snooping的知识点 1.1、DHCP snooping 概述&#xff1a; ①DHCP Snooping使能DHCP的一种安全特性&#xff0c;用于保证DHCP客户端从合法的DHCP服务端获取IP地址。DHCP服务器记录DHCP客户端IP…

pycharm 找不到conda环境

参考&#xff1a;新版Pycharm解决Conda executable is not found-CSDN博客

[C++刷题] 基础小知识点(1) 乘方函数pow()

乘方 pow() 该函数在math.h头文件中 例如: 求圆的面积公式 s3.14*pow(r,2); 例题: #include<iostream> using namespace std; #include<math.h>) int main() {int h;int r;cin >> h >> r;double v h * 3.14 * pow(r, 2);int ret 0;if (v > 200…

slam系列4:nerf和3dgs

常用的3维表示法&#xff1a; NeRF属于是density的模型&#xff0c;模型的参数如下&#xff1a; 传统的 3D 模型表示方法&#xff0c;如 离散的Mesh 和点云&#xff0c;以及连续的 Nerf&#xff0c;通常面临着一个主要问题&#xff1a;随机采样过程中产生的噪声&#xff0c;这…

P5430 7.68T U.2 NVME SBFPF2BU076T001 Solidigm固态硬盘

SBFPF2BU076T001 Solidigm P5430 7.68T U.2 NVME企业级固态硬盘 Solidigm针对企业应用推出D5-P5430固态硬盘&#xff0c;针对主流和读取密集型应用程序进行了优化&#xff0c;面向大量企业工作它采用PCIe Gen 4总线与QLC类型NAND颗粒&#xff0c;提供大量的存储密度并降低总拥…

《云计算网络技术与应用》实训6-1:配置KVM虚拟机使用NAT网络

任务1、计算节点基础环境准备 1. 使用VMware安装CentOS 7虚拟机&#xff0c;安装时记得开启CPU虚拟化&#xff0c;命名为“KVMC6”。 2. &#xff08;网卡配置和之前的一样&#xff0c;都用100网段&#xff09;网关设置为192.168.100.1&#xff0c;地址段为192.168.100.10-25…

数据分析:R语言计算XGBoost二分类模型的SHAP值

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍SHAP用途计算方法:应用加载R包导入数据建模平均SHAP值计算单个样本的每个特征的SHAP值蜜蜂图依赖图单个样本的SHAP解释(Force Plot)其他方法计算SHAP值单个个体预测结果系统信息…

轻松掌握:如何查找家中WiFi的IP地址

在如今数字化生活的时代&#xff0c;WiFi已成为我们日常生活中不可或缺的一部分。无论是上网冲浪、在线学习、还是远程办公&#xff0c;稳定的WiFi连接都显得尤为重要。然而&#xff0c;有时我们可能需要了解家中WiFi的IP地址&#xff0c;以便进行网络设置、故障排查或进行其他…

基于springboot留守儿童爱心网站

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 系统展示 【2024最新】基于JavaSpringBootVueMySQL的&#xff0c;前后端分离。 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;…

爬虫之数据提取

HTML数据提取 这一片文章, 我们一起学习如何利用HTML标签来提取数据。 我们打开二手房网站: 我们打开开发者工具, 找到请求: 这次我们找的请求, 和以前的不一样了, 所以这里面带大家找一找, 以前我们找的请求都是json格式的响应数据, 那今天由于我们要学习如何提取html数据, …

Jenkins实践(三):分包编译部署到Maven私仓

本文主要是针对springboot多模块项目&#xff0c;参数化构建、分包部署到maven私仓的记录。本文以上篇文章为基础进行记录。 系列文章&#xff1a; Jenkins入门&#xff08;一&#xff09;&#xff1a;从搭建到部署第一个Springboot项目(踩坑记录)_ub24.04安装jenkins-CSDN博…

LinkedList和链表(上)

1. 顺序表ArrayList的缺点和优点 优点: 1> 在给定下标进行查找的时候,时间复杂度是O(1) 缺点: 1> 插入数据必须移动其他数据,最坏情况下,插入到0位置,时间复杂度为O(N) 2> 删除数据也需要移动数据,最坏情况下,就是删除0位置.时间复杂度为O(N) 3> 扩容之后(1.5倍扩容…

《深度学习》OpenCV 物体跟踪 原理及案例解析

目录 一、物体跟踪 1、什么是物体跟踪 2、步骤 1&#xff09;选择跟踪算法 2&#xff09;初始化跟踪器 3&#xff09;在每个视频帧上执行跟踪 4&#xff09;可选的重新初始化 3、原理 二、案例实现 1、完整代码 1&#xff09;使用方式 2&#xff09;运行结果 2、关…

麒麟桌面版v10 SP1以docker方式安装达梦数据库

安装docker 0.切换root用户&#xff08;可以不切换&#xff0c;但要注意权限问题&#xff0c;我是用root&#xff09; ymym-pc:~/桌面$ whoami ym ymym-pc:~/桌面$ sudo -i rootym-pc:~# whoami root rootym-pc:~# 1.查看系统版本 [rootlocalhost opt]# cat /etc/os-release…

java类和对象(上)

前言&#xff1a; 不知道大家有没有将java方法的使用熟记入心呢&#xff1f;如果没有的话&#xff0c;可以打开博主的上一篇博文阅读哦&#xff0c;在这里谢谢大家一路的陪伴。也希望我的内容能够帮到你更快的掌握java语言的学习。接下来我们要讲的是java类和对象。让我们整理…

最新Mac优化清理工具CleanMyMac X 4.15.6 for mac中文版图文教程

CleanMyMac X mac版下载是一款功能更加强大的系统优化清理工具&#xff0c;软件只需两个简单步骤就可以把系统里那些乱七八糟的无用文件统统清理掉&#xff0c;节省宝贵的磁盘空间。CleanMyMac X for mac相比于 CleanMyMac3来说&#xff0c;功能增加了不少&#xff0c;比如新增…

Java并发 - AQS之CountDownLatch

文章目录 基本使用源码分析awaitcountDowngetCount 可重置的CountDownLatch总结 CountDownLatch是一个多线程同步工具类&#xff0c;允许一个或多个线程等待&#xff0c;直到在其他线程中执行的一组操作完成。主要用来解决一个线程或多个线程等待另外多个线程的场景。 初始化需…