当前课程知识点:Java程序设计 > 第三章 类的重用 > 3.2-Object 类 > 3.2-Object 类
大家好 欢迎回来继续学习
JAVA语言程序设计
这一节我们来学习Object类
在JAVA里面Object类
是所有其它类的
直接或间接的超类
所以在Object类里面
它就规定了所有其它类中
都应该具有的共同的属性
还有行为
接下来我们就来了解一下
Object类里面
有哪些主要的方法
在Object类中
有一个叫做getClass的方法
它的功能是获取
当前对象所属类的信息
它返回的是一个Class对象
另一个方法toString
我们已经见过多次了
它是用来将一个类的对象
转换成字符串的这样的方法
它返回表示当前对象
本身有关信息的这个字符串对象
我们在前面章节例题中也看到了
这个默认的toString挺不好用的
那我们自己可以按照
我们自己的需求去设计
从对象转换成字符串如何转换
我们可以把它覆盖掉
还有一个方法叫equals方法
这个方法并不像它名字
表达的那样
是说比较相等关系的 不是的
它天然的功能是什么呢
是比较两个对象的引用
是否指向同一个对象
是同一关系的判断
如果两个对象引用
指向的是同一个对象
这个方法就返回一个true
也就是真
否则返回假 false
如果我们想用一个
已经存在的对象
去产生一个副本
也就是复制当前这个对象
产生一个克隆的拷贝一个副本
那这个时候就可以用
clone这个方法
另外hashCode这个方法
它的功能是返回对象的
哈希代码值
还有一个finalize方法
是干什么用的呢
它是在对象被回收的那个时刻
自动被执行的
通常我们用
这个方法体里面的代码
来完成资源释放的工作
那接下来我们就详细的
介绍一下这一些方法
为了了解这个equals方法
为了在需要的时候
我们可以按照自己的意愿
去覆盖这个equals方法
我们首先要了解一下
相等和同一这两种情况的区别
什么是相等呢
相等就是说两个对象
它具有相同的类型
相同的属性值
那这个时候当然我们就认为
这两个对象是相等的
什么是同一呢
如果两个引用变量
指向的是同一个对象
那这个时候
就称这两个引用变量同一
就identical
那如果说两个引用变量同一
那么它指向的对象肯定相等了
同一个对象自己
它当然是相等的
如果说两个对象
它是相等的
那不一定它们是同一个对象
那内置的基本运算里边的
关系运算有一个比较运算符
是判断运算附两侧的对象
是否相等的
实际上当比较运算附
用来判断对象的引用的时候
它比较的是这两个引用是否相等
也就是是否同一
你想如果两个引用变量是相等的
当然就意味着
它们指向的是同一个对象
所以比较运算符
天然的也就只能用来判断
两个引用变量
它们是否指向同一个对象
所以用比较运算符
直接是没法判断
两个不同对象是否相等的
这个例题是利用
相等比较运算符
来判断两个引用是否同一
我们看到在这个主方法中
构造了两个BankAccount对象
这个银行帐户对象
是在前面例子中我们看到了
这个银行帐号类的声明的
构造这样两个对象
然后它的属性值是一样的
也就是两个对象中
包含的所有属性值都相同
在我们通常意义上讲
就要认为这两个对象是相等的了
但是这个例题中比较的是什么呢
比较的是指向这两个对象的
引用a引用b它俩是否相等
判断引用是否相等
实际上就是判断
它们是否指向同一个对象
因为这是两个对象
它肯定不是同一个
所以运行结果是NO
所以这几个典型的
判断两个引用是否同一的例子
由于equals方法
是声明在Object类里面的
所以所有的JAVA类里面
都继承了都有这个equals方法
但是这个equals方法
它真的是像这个方法名
表达的那样
是在比较相等关系吗
我们来看看
实际上这个Object类里面的
equals方法
它大致就是这样实现的
我们看这个代码的例子
基本上是这样实现的
就是说它判断当前对象的引用
这个this引用
跟方法的参数里面
传过来的这个对象引用
是不是相等的
判断对象引用是否相等
那也就判断这两个引用
是否指向同一个对象
还是判断同一关系
它没有判断相等关系
这个例子是对equals方法
它的功能的一个验证
同样我们还是构造了
两个BankAccount对象
两个银行帐户对象
然后通过a引用
去调用equals方法
以b引用作为参数
那么结果是什么呢
运行结果仍然是NO
所以这个equals方法
它天然的功能
也是判断是否同一
而不是比较两个对象是否相等
如果我们想使用equals方法
来判断两个对象是否相等
真判断这种相等关系的话
就不能直接使用
从Object类里面
继承过来那个equals方法了
那我们就要怎么办呢 自己写
重写equals方法的方法体
去覆盖继承过来的equals方法
那比如说String类里面
就覆盖了equals方法
所以我们可以比较
两个String对象
两个字符串是否相等
当我们在覆盖equals方法的时候
一定要注意这个方法原形
跟Object里面
那个equals方法的方法原形
必须是一样的才可以
在这个例子中
我们在银行帐户类中
覆盖一下这个equals方法
我们看这个覆盖的equals方法体
首先要比较一下这个参数对象
它跟当前对象
是否属于同一个类型
因为参数接收过来以后
就不知道
原来的实参类型是什么了
从这个参数类型声明上
只能看到它是Object类型
所以要调用getClass方法
去比较一下参数对象所属的类
与当前要跟它比较的这个对象
所属的类是不是同一个类
如果类型都不一样
当然它们不相等
就返回false
在类型同样的情况下
将参数对象强制转换成
BankAccount类型
然后用来初始化
这个BankAccount引用b
通过BankAccount引用b
才可以去使用
BankAccount类中
自己声明的方法
所以这个时候
我们就可以去比较
当前this对象
它的OwnerName
还有b引用所指向的对象
它的OwnerName
用OwnerName方法
就会取出户名
比较户名是否相等
然后同样的道理
比较帐号是否相等
比较它的余额是否相等
当这三个都相等的情况下
就认为这两个对象是相等的
所以这实现了
对象是否相等的这种比较
覆盖了equals方法
接下来这个例子中
我们在Apple类中
覆盖了equals方法
我们来看这个equals方法体
首先对参数传进来的对象
也是要进行判断
要判断它跟当前对象
是不是属于同一个类型的
那么这次是用的
instanceof这个运算
判断这个参数对象
是否Apple类型的对象
如果是那么再进行后续的比较
如果不是直接返回false
类型都不相符
当然它不相等
在类型一致的情况下
就将这个参数对象引用
强制转换成Apple类型的
这样就可以调用Apple类里面
自己声明的方法了
去取它的color属性出来
取它的成熟度ripe属性出来
比较颜色是否一样
成熟度是否一样
当两者都一样的时候
就可以返回一个true
只要有哪个不一样
那么当然就返回false
这个也是实现了
真正的对象相等比较
hashCode方法
是一个返回对象散列码的方法
hashCode方法
它到底实现了什么样的功能呢
它是返回对象的散列码
那么实现的时候有这样的规定
也就是要求在一个JAVA程序的
一次执行过程中
如果对象相等比较
所使用的信息没有被修改的话
那么对同一个对象
如果多次执行hashCode方法
那每次都应该返回同一个整数
在一个程序的
不同次的执行过程中
这个对象的hashCode的方法
返回值就不必一致了
第二个如果依照equals方法来讲
两个对象它是相等的
那么在这两个对象上
你要分别调用hashCode方法
它得到的返回的值
也应该是相同的
如果依据equals方法
两个对象不相等
那这个时候
倒并不要求在这两个对象上
调用hashCode方法
返回值一定不同
当然能够不同是更好
如果Object类中
定义的这个hashCode方法
它的实现要是合理的话
这个方法就能为不同的对象
返回不同的整数值
比如说一个比较典型的实现方法
就是将对象的内部地址
经过一个转换
转换成一个相关的整数返回
但是JAVA语言
它并没有规定必须如何实现
hashCode方法
只是给出了这样几个要求
这个clone方法的功能
就是根据一个已有的对象
来创建新的对象
也就是复制 也就是克隆
我们要能够使用clone方法
来复制对象
那么首先你就要去覆盖
这个clone方法
因为在Object类中
clone方法被定义为protected
它是保护的
所以在类外是不能够访问它的
所以我们需要
把它覆盖为public
而且除此而外
还要去实现一个
Cloneable接口
实现这个接口
不需要你再去实现什么
接口中的方法体
它只是一个标记
只是表示这个对象
是可以被克隆的
它赋予一个对象被克隆的能力
比如说我们定义一个
MyObject类
让它implements
实现了cloneable接口
那就表示着我允许
我这个MyObject类的对象被克隆
关于接口我们会在
后续章节中学习
这个finalize方法
它不是我们写代码
去显式调用的
是在一个对象即将消亡的时候
也就是垃圾回收器
它去把这个对象的存储空间
回收的时候
在这个时刻被自动调用的
垃圾回收器什么时候
会去回收这个对象的空间呢
原则上讲一个对象
如果它不再被使用了
就有可能随时被回收
但是在什么时刻
按照什么次序被回收
这些并不保证
我们在覆盖这个
finalize方法的时候
首先要在第一句
去调用它超类的finalize方法
在这个方法中
通常我们都会去释放一些
在对象存续期间所占用的资源
但是这个它到底的执行的早晚
按照什么次序执行
这些应该说可以影响到
你程序的效率
但是绝对不应该影响到
你程序的正确性
因为我刚才说了
这个finalize方法
在什么时刻会被调用
这是不确定的
因为你的对象什么时刻被回收
这一点是不确定的
那么这个getClass方法
是获取这个对象所属类的
相关信息的一种方法
它返回的是一个Class对象
这个getClass方法
它是一个final方法
返回的Class对象
代表这个对象所属的类
我们通过这Class对象
可以查询类的各种信息
比如说类名 它的超类
它到底实现了哪些接口
这些接口的名字
这个都可以查出来
比如说我们看这个小例子里面
我们可以调用getClass方法
去获得你传进来的这个对象引用
它指向的对象属于哪个类
把那个类信息得到
然后再调用getName
就可以把它的类名找出来
这时候我们可以输出
这个对象它属于什么类了
它的类名可以找出来了
另外还有三个方法
是与线程相关的
notify notifyAll和wait
这三个方法都是final方法
因为与线程相关太关键了
不能随便改写
写错了这系统就搞乱了
所以这三个方法
都是不能覆盖的
关于这三个方法
我们在这门课中先不做介绍
因为我们在这门课中
不介绍多线程的问题
好 在这一节中
我们学习了Object类里面的
几个主要的方法
一些方法我们继承过来以后
可以覆盖
形成每个子类的特殊实现
那final方法
也叫终结方法
就是不能覆盖的
那接下来我会详细介绍
final方法 也叫终结方法
好这一节的内容就是这些
-1.0-导学
--1.0-导学
-1.1-Java与面向对象程序设计简介
--第一章 Java语言基础知识--1.1-Java与面向对象程序设计简介
-1.2-基本数据类型与表达式
-第一章 Java语言基础知识--1.2-基本数据类型与表达式
-1.3-数组
--1.3.1-数组
-第一章 Java语言基础知识--1.3-数组
-1.4-算法的流程控制
--第一章 Java语言基础知识--1.4-算法的流程控制
-1.5-第一章小结
-第一章编程练习题
-课件
--外部链接
-Java环境配置、Eclipse使用、Helloworld程序详解
--使用eclipse建立Java项目、编写和运行Java程序
-Java数据类型
--Java整数类型
--Java浮点类型
--数据类型实战
--数据类型转换
--Java强制类型转换精度损失示例与表达式中的数据类型转换
-Java数组
-Java变量
--Java的变量
-命令行参数
--命令行参数的介绍
-2.0-导学
--2.0-导学
-2.1-面向对象方法的特性
--第二章 类与对象--2.1-面向对象方法的特性
-2.2-1-类声明与对象创建
--第二章 类与对象--2.2-1-类声明与对象创建
-2.2-2-数据成员
--第二章 类与对象--2.2-2-数据成员
-2.2-3-方法成员
--第二章 类与对象--2.2-3-方法成员
-2.2-4-包
--2.2-4-包
--第二章 类与对象--2.2-4-包
-2.2-5-类的访问权限控制
--第二章 类与对象--2.2-5-类的访问权限控制
-2.3-1-对象初始化
--第二章 类与对象--2.3-1-对象初始化
-2.3-2-内存回收
--第二章 类与对象--2.3-2-内存回收
-2.4-枚举类
--2.4-枚举类
--第二章 类与对象--2.4-枚举类
-2.5-应用举例
--2.5-应用举例
-2.6-第2章小结
-第二章编程练习题
-课件
--第二章课件
-3.0-导学
--3.0-导学
-3.1.1-3.1.2-类继承的概念和语法
--第三章 类的重用--3.1.1-3.1.2-类继承的概念和语法
-3.1.3-隐藏和覆盖
--第三章 类的重用--3.1.3-隐藏和覆盖
-3.2-Object 类
--第三章 类的重用--3.2-Object 类
-3.3-终结类与终结方法
--第三章 类的重用--3.3-终结类与终结方法
-3.4-抽象类
--3.4-抽象类
--第三章 类的重用--3.4-抽象类
-3.5-泛型
--3.5-泛型
--第三章 类的重用--3.5-泛型
-3.6-类的组合
--3.6-类的组合
-3.7-小结
--3.7-小结
-第三章编程练习题
-课件
--课件
-4.0-导学
--导学
-4.1-接口
--接口
--第四章 接口与多态--4.1-接口
-4.2.1-4.2.2-类型转换
--类型转换
--第四章 接口与多态--4.2.1-4.2.2-类型转换
-4.2.3-方法的查找
--方法的查找
--第四章 接口与多态--4.2.3-方法的查找
-4.3-多态的概念
--多态的概念
--第四章 接口与多态--4.3-多态的概念
-4.4-多态的应用举例
--多态的应用举例
--第四章 接口与多态--4.4-多态的应用举例
-4.5-构造方法与多态性
--构造方法和多态性
--第四章 接口与多态--4.5-构造方法与多态性
-4.6-本章小结
--本章小结
-第四章编程作业
-课件
--课件
-5.0-导学
--5.0-导学
-5.1.1-5.1.2-异常处理的概念
--第五章 输入输出--5.1.1-5.1.2-异常处理的概念
-5.1.3-5.1.5-异常的处理
--第五章 输入输出--5.1.3-5.1.5-异常的处理
-5.2-输入输出流的概念
--输入输出流的概念
--第五章 输入输出--5.2-输入输出流的概念
-5.3.1-写文本文件
--写文本文件
--第五章 输入输出--5.3.1-写文本文件
-5.3.2-读文本文件
--读文本文件
--第五章 输入输出--5.3.2-读文本文件
-5.3.3-写二进制文件
--写二进制文件
--第五章 输入输出--5.3.3-写二进制文件
-5.3.4-读二进制文件
--读二进制文件
-5.3.5-File类
--File类
-5.3.6-处理压缩文件
--处理压缩文件
-5.3.7-对象序列化
--对象序列化
-5.3.8-随机文件读写
--随机文件读写
-5.4-本章小结
--本章小结
-课件
--课件
-6.0-导学
--导学
-6.1-Java集合框架介绍
--第六章 对象群体的组织--6.1-Java集合框架介绍
-6.2-主要接口及常用的实现类
--第六章 对象群体的组织--6.2-主要接口及常用的实现类
-6.3-常用算法
--常用算法
-6.4-数组实用方法
-6.5-基于动态数组的类型(Vector, ArrayList)
--基于动态数组的类型(Vector, ArrayList)
-6.6-遍历Collection
-6.7-Map接口及其实现
-6.8-第6章小结
--第6章小结
-课件
--课件
-7.0-导学
--导学
-7.1-绘图
--绘图
-7.2-Swing基础
--Swing基础
-7.3-Swing的层次
--Swing的层次
-7.4-布局管理
--布局管理
-7.5-内部类
--内部类
-7.6-事件处理的基本概念
-7.7-事件派发机制
--事件派发机制
-7.8-顶层容器
--7.8-顶层容器
-7.9-中间层容器(一)
-7.10-中间层容器(二)
-7.11-原子组件(一)
-7.12-原子组件(二)
-7.13-原子组件(三)
-7.14-其它Swing特性
-7.15-第7章小结
-课件
--课件