内部类, Comparable接口, Comparator接口, Cloneable接口 ---java

目录

一. 内部类

1.1 静态内部类

1.2 实例内部类

1.3匿名内部类

二. 接口的使用实例 

2.1 Comparable接口

2.2 Comparator接口 ---比较器

2.3 Cloneable接口 

深拷贝浅拷贝 


一. 内部类

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。在 Java 中, 可以将一个类定义在另一个类或者一个方法的内部, 前者称为内部类,后者称为外部类 。内部类也是封装的一种体现。
public class OutClass {
        class InnerClass {
        }
}
// OutClass 是外部类
// InnerClass 是内部类

注:内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件 ,命名格式:外部类名字$内部类名字.class

内部类可以分为四类:

1. 静态内部类

2. 实例内部类

3. 匿名内部类(最常用)

4. 局部内部类 (不常用,不做讲解)

1.1 静态内部类

static修饰的内部成员类称为静态内部类。  

上述代码, 我们可以看到,

1. 在静态内部类中定义的成员变量(方法), 可以是static修饰的,

2. 在静态内部类中的成员方法, 可以直接访问在静态内部类中定义的成员变量(方法)在外部类中定义的static修饰的变量(方法), 但不能直接访问外部类中没有被static修饰的变量

 3. 想要在静态内部类的方法中访问外部类的成员变量, 需要创建一个外部类型的对象, 通过对象去访问.

4. 在外部类中创建一个方法, 在这个方法里面, 可以直接创建静态内部类的对象

5. 在外部类之外, 想要创建静态内部类对象,  不需要先创建外部类对象, 必须通过外部类.  去使用

1.2 实例内部类

即未被 static 修饰的成员内部类。

 

由上述代码, 我们可以得到:

1. 实例内部类中不能定义static修饰的变量(方法) , 如果想定义, 需要加final

 2 . 在外部类中创建一个方法, 在这个方法里面, 可以直接创建实例内部类的对象

 3. 在外部类之外, 想要创建实例内部类对象,  需要先创建外部类对象, 通过外部类对象的引用外部对象. 去创建实例内部类对象

4. 在实例内部类的方法中, 都可直接访问外部类和内部类中的任意访问限定符修饰的成员变量(方法) 

 5. 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的,  加this. 还访问自己的.

如果要访问外部类同名成员:外部类名称.this.同名成员名字

或像静态内部类一样, 创建一个外部类对象, 对对象的引用

1.3匿名内部类

我们先看一下什么是匿名对象

 如果以后的场景是, 只是用一次对象, 那么可以使用匿名对象.

使用匿名内部类, 首先我们先创建一个接口

正常情况下我们是这样使用的

而匿名内部类, 可以不用创建类TestA, 直接匿名实现接口, 并对其重写

 或更高阶的写法:

 当然, 也可以匿名new类. 

二. 接口的使用实例 

Java 中内置了一些很有用的接口:

2.1 Comparable接口

定义两个字符串

如何比较两个字符串的大小呢?

显然, 是错误的,java当中, 不可以直接比较引用类型的大小 

那么, 我们就可以借助String类型里面的compareTo()方法进行比较

 按住Ctrl我们点进compareTo发现 :

这个方法是通过重写接口中的方法得来的, 那么我们点进去黄框, 就会发现:

原来String类型, 可以进行字符串的比较, 是因为引用了Comparable这个接口, 然后在类中重写compareTo这个方法实现的

 那么同理, 当我们自定义一个类, 创建两个对象时, 想要比较两个对象的大小, 我们就可以通过implements Comparable<>, 并在类中重写compareTo方法, 根据自己的需求, 自定义要比较的标准.

举例:

我们也可以以姓名为标准进行比较:

 再举例:

定义一个数组, 通过Arrays.sort()对数组进行排序:

运行时我们发现报错:

 原因是, Arrays.sort() 不知道以什么标准进行比较

注意事项: 对于 sort 方法来说, 需要传入的数组的每个对象都是 "可比较" 的, 需要具备 compareTo 这样的能力. 通过重写 compareTo 方法的方式, 就可以定义比较规则.

所以Student类, 需要实现Comparable接口, 并重写compareTo方法 

结果: 

2.2 Comparator接口 ---比较器

比较什么, 就定义一个类, 实现Comparator接口, 重写compare方法, 将比较的对象当做参数传递过去,  非常灵活

 

再如上述对数组排序时, 可以使用Arrays.sort(数组名, 比较器), 这样在比较时, 就会使用比较器的方法进行排序. 

2.3 Cloneable接口 

现在, 我们定义一个对象, 我们想把第一个对象克隆到第二个对象

我们看到, Object类中有clone()方法, 我们想拿过来直接用, 发现:

不允许我们直接用, 我们点进去clone()方法可以看到:

它是被protected修饰的, 我们学过, 在不同包中, 想要访问protected修饰的方法, 必须是在子类中访问, 需要通过super进行访问, 所以我们要对clone方法进行重写. 

利用快捷方法:Alt + Insert

这个方法就被创建好了. 

我们看到:

返回类型是Object,  所以我们要调用这个方法时, 要进行向下转型

后面跟着一串throws CloneNotSupportedException, 这个我们先不管后面讲, 先照抄在main方法后面. 

此时运行我们发现报错:

解决方法:

要实现一个Cloneable接口, 表示此类可以被克隆. 

到此为止, 才算克隆成功. 

我们点进去Cloneable接口可以看到:

 

里面什么也没有, 我们管这种接口叫做空接口/标记接口

一个类实现了空接口/标记接口, 那么表示当前这个类, 是可以被怎么样的, 如实现Cloneable, 表示此类可以被克隆. 

 

深拷贝浅拷贝 

什么是深拷贝浅拷贝呢?

我们看一个例子:

在对象里创建一个对象:

上述代码我们修改了person2中的m的money的值, 理论上来说输出的结果应该为:

person1还是6.6 ,person2被改成9.9 ,但是当我们运行起来后发现:

person1的值也被改了. 

这是为什么呢? 我们画图理解一下:

所以person1, person2修改之前都是6.6. 此时, 两个m都指向同一块空间

所以, 修改money的值, person1和person2都变. 

这就是浅拷贝, 只拷贝了原来的对象, 但对象里的对象没有被拷贝. 

那么同理:深拷贝是指完全克隆出一个独立于原来的对象的对象 

那么, 上述代码, 如果想要达到深拷贝效果, Money这个类必须也是一个可以拷贝的类, 所以Money类要实现Cloneable接口, 并重写父类中的clone方法.

这样我们就做好了准备工作, 但是在哪里怎么调用这个方法呢?

在Person的clone()里:

 

 

 

此时person1的m 和person2的m 是两个独立的对象, 相互不耽误. 所以, 修改person2的m的money的值, person1不变, person2变.

完整代码如下:

class Money implements Cloneable{
    public double money = 6.6;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public String name;
    public Money m;
    public Person(String name) {
        this.name = name;
        m=new Money();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
       Person tmp = (Person) super.clone();
       tmp.m = (Money) this.m.clone();
       return tmp;
    }
}
public class Test2 {
    public static void main(String[] args)throws CloneNotSupportedException{
        Person person1 = new Person("zhangsan");
        Person person2 =(Person) person1.clone();
        System.out.println("person1修改之前:"+person1.m.money);
        System.out.println("person2修改之前:"+person2.m.money);
        person2.m.money = 9.9;
        System.out.println("person1修改之后:"+person1.m.money);
        System.out.println("person2修改之后:"+person2.m.money);
    }
}

可见, 是不是深拷贝, 是要看程序猿实现的怎么样.

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

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

相关文章

机器学习——支持向量机(SVM)

1.线性支持向量机 1.1数学模型 机器学习最终都是求解目标函数的最优问题&#xff1b; 一般都是讲问题转化为最小值来求解。 数学模型获得是一个不等式约束的最小化问题&#xff0c;求解时可通过构建拉格朗日函数求解。 1.2 拉格朗日函数及对偶问题求解 1.3 SMO算法求解 SMO算…

vue中的keep-alive详解与应用场景

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue-keep-alive 目录 一、Keep-alive 是什么 二、使用场景 三、原理分析 四、案例实现 activa…

虹科干货 | 适用于基于FPGA的网络设备的IEEE 1588透明时钟架构

导读&#xff1a;在基于FPGA的网络设备中&#xff0c;精确的时间同步至关重要。IEEE 1588标准定义的精确时间协议&#xff08;PTP&#xff09;为网络中的设备提供了纳秒级的时间同步。本文将介绍虹科提供的适用于基于FPGA的网络设备的IEEE 1588透明时钟&#xff08;TC&#xff…

flink源码分析之功能组件(三)-rpc组件

简介 本系列是flink源码分析的第二个系列,上一个《flink源码分析之集群与资源》分析集群与资源,本系列分析功能组件,kubeclient,rpc,心跳,高可用,slotpool,rest,metrics,future。 本文解释rpc组件,rpc组件用于个核心组件,包括作业管理器,资源管理器和任务管理器之…

uni-app 离线打包安卓Apk(小白上手)

场景&#xff1a; 在使用uni-app 开发apk时&#xff0c;使用云打包有次数限制。尤其对于测试阶段是无比难受的&#xff0c;通常是浪费打包次数进行打包或者通过usb 给测试机更新开发环境&#xff0c;但这都是无比漫长的过程 尤其有多个测试机真的是噩梦般的存在 下载离线打包示…

基于mpvue实现的cnode社区demo(附精选源码32套,涵盖商城团购等)

社区类目没有开放给个人开发者&#xff0c;所以没能上线。 预览 项目配置文件&#xff0c;更改appid {"description": "项目配置文件","setting": {"urlCheck": true,"es6": false,"postcss": false,"minif…

扫地机器人市场持续火爆,景联文科技数据采集标注方案助力扫地机器人智能化升级

随着消费者对智能家居和清洁卫生的需求增加&#xff0c;扫地机器人市场规模不断扩大。市场竞争也日益激烈&#xff0c;各品牌都在努力提升产品性能和服务质量&#xff0c;以获取更大的市场份额。 IDC的统计数据显示&#xff0c;今年双十一前两周&#xff08;2023年10月23日至20…

stream流和方法引用

1.Stream流 1.1体验Stream流【理解】 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合&#xff0c;存储多个字符串元素把集合中所有以"张"开头的元素存储到一个新的集合把"张"开头的集合中的长度为3的元素存储到一个新的集合遍历上一步得到的集…

jsoup登录日志平台后调企业微信机器人自动发送错误日志告警

一、需求&#xff1a;错误日志Top10告警发送 二、需求分解 jsoup实现登录&#xff0c;获取到cookie和token等用户鉴权信息获取接口相应的key值调用日志平台错误日志Top榜接口&#xff0c;查询到结果集调用企业微信机器人发送消息接口加上定时任务&#xff0c;可以实现定时发送…

顺子日期(14)

顺着日期 public class Main {public static void main(String[] args) {int res 0;//2022年int[] days new int[] {31,28,31,30,31,30,31,31,30,31,30,31};//31,28,31,30,31,30,31,31,30,31,30,31//一三五七八十腊//构造2022年每一天的日期yyyymmddStringBuffer date new…

用python实现kindle文件转换pdf

上一篇文章讲了下用工具转换相关的格式&#xff1a;https://blog.csdn.net/weixin_42019349/article/details/134654695 今天来分享一个python库实现上述功能&#xff0c;实现文件转换自由 ^_^ 主角就是pypandoc库 # 安装方式 pip install pypandoc# pypandoc主要有三个函数…

ModuleNotFoundError: No module named ‘mdtex2html‘ module已经安装还是报错,怎么办?

用streamlit运行ChatGLM/basic_model/web_demo.py的时候&#xff0c;出现了module not found&#xff1a; ModuleNotFoundError: No module named mdtex2html Traceback: File "/home/haiyue/.local/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script…

机器学习的复习笔记3-回归的细谈

一、回归的细分 机器学习中的回归问题是一种用于预测连续型输出变量的任务。回归问题的类型和特点如下&#xff1a; 线性回归&#xff08;Linear Regression&#xff09;&#xff1a;线性回归是回归问题中最简单的一种方法。它假设自变量与因变量之间存在线性关系&#xff0c…

普通表计读数开发思路

一、普通表计类型介绍&#x1f349; 常见的普通表计有SF6&#xff0c;压力表&#xff0c;油位表&#xff08;指针类&#xff09;等。 图1&#xff1a;( 压力表) 图2&#xff1a;&#xff08;油位表-指针类&#xff09; 图3&#xff1a;&#xff08;SF6表&#xff09; 图4:&a…

巧妙之中见真章:深入解析常用的创建型设计模式

设计模式之创建型设计模式详解 一、设计模式是什么&#xff1f;二、模板方法2.1、代码结构2.2、符合的设计原则2.3、如何扩展代码2.4、小结 三、观察者模式3.1、代码结构3.2、符合的设计原则3.3、如何扩展代码3.4、小结 四、策略模式4.1、代码结构4.2、符合的设计原则4.3、如何…

K 最近邻算法

K 最近邻算法 简单 KNN海伦约会手写数字识别KNN 算法的优缺点 K 最近邻&#xff08;K-NearestNeighbor&#xff0c;KNN&#xff09;算法&#xff0c;是 1967 年由 Cover T 和 Hart P 提出的一种用于分类与回归的方法。 基本原理&#xff1a;存在一个带标签的数据集&#xff08;…

C语言第三十五弹---打印九九乘法表

C语言打印九九乘法表 思路&#xff1a;观察每一行可以看出乘号右边的一行值都是相同的&#xff0c;而乘号左边不断变化&#xff0c;所以使用嵌套循环&#xff0c;控制好 乘号左右值变化的条件即可。 #include <stdio.h>int main() {for (int i 1; i < 9; i){for (in…

【微服务】java 规则引擎使用详解

目录 一、什么是规则引擎 1.1 规则引擎概述 1.2 规则引擎执行过程 二、为什么要使用规则引擎 2.1 使用规则引擎的好处 2.1.1 易于维护和更新 2.1.2 增强应用程序的准确性和效率 2.1.3 加快应用程序的开发和部署 2.1.4 支持可视化和可管理性 2.2 规则引擎使用场景 三、…

开源四轴协作机械臂ultraArm激光雕刻技术案例!

注意安全事项 开始之前&#xff0c;请确保您已采取适当的安全措施&#xff0c;例如用于激光操作的防护眼镜、灭火器和通风良好的区域。 引言 随着科技的不断进步&#xff0c;激光雕刻技术已经成为当今制造行业中不可或缺的一部分。它以其高精度、高效率和广泛的材料适应性&…

JAVA的一些便捷性方法(Object)

在IDEA中&#xff0c;如何查看JDK的源码&#xff1f; CTRL B; 常用方法&#xff1a; 1.equals&#xff08;&#xff09; booleanequals(Object obj) 指示其他某个对象是否与此对象“相等”。 与 的比较&#xff1a; &#xff0c;即可判断基本类型&#xff0c;也…