再谈JAVA

Object:所有类的超类
Object是所有包的始祖,每个类都是由这个类扩展来的,只要没有明确的指出指定的超类,那么超类基本上都是Object,当声明一个对象时可以将Object当成对象类型,但是要想使用子类的具体操作,还需要对对象进行类型转换,适用对象的原始类型。在Java中除了基本数据类型所有都扩展了Object。
equals方法
检测一个对象与另外一个对象是否相等。在Object类中,将判断两个对象是相同的引用,如果具有相同的引用,那么他们就相等,在实际中没什么实际意义,然而经常需要检测两个对象的实际意义,如果两个对象的状态相等,例如两个对象姓名薪水雇佣日期一样·,那么就等于这两个对象相等。在子类中定义equals方法时,首先调用equals。如果检测失败,那么对象就不可能相等,反之如果相等就该比较子类中的实例域。
相等测试与继承
如果隐式和显示不是同一类,怎样使用equals方法检测,使用instanceof,这种方法不仅没有解决是不是子类的问题,还会导致其他问题。equals方法要求规范如下:

  1. 自反性:对于任何x,x.equals(x),都返回true。
  2. 传递性:,例如x,y,z,如果x,y使用equals返回true,y,z返回true,那么x,z返回true,
  3. 对称性:对于任何x,y,不论哪个是隐式,显示,都在equals方法中返回true。
  4. 一致性:如果两个对象没有发生什么变化,都在equals方法中成立。
  5. 对于任意非空x,都有x.equals(null)返回false。

然而就对称性来说,如果两个对象不是同一个类,如果两个对象是继承关系,调用equals方法,在equals中用instanceof检测,试想,这种检测不会让两边对象都成立,所以这种检测并不完美。
某些人不认为使用getclass方法,因为不符合置换原则,例如一个AbstractSet中有一个equals方法,有两个子类,都需要对任意两个集合进行比较。然而,集合非常特殊,因为他将equals方法定义为final,这是因为没有任何一个子类重定义集合是否需要相等的语义(事实上并没有使用final语句,因为他要让子类选择更加高效的算法对集合进行是否相等的检测)

  1. 如果两个子类具有自己的相等的概念,那么就是用getclass方法检测
  2. 如果由超类决定相等的概念,那么就可以使用instanceof进行检测,这样可以在不同子类的对象之间进行相等的比较。

例如在经理和雇员的例子中,只要对等的域相等就认为两个对象相等,,如果所有都相等,就奖金不相等,就认为是不同的,这种就是用getclass。
但是使用雇员ID作为检测标准,这种相等适合所有子类,就可以使用instanceof进行检测。并且应该将超类equals成名为final。
下面给出了一个编写equal方法的建议

  1. 显示的参数命名为otherObject。稍后将它转换为另一个叫做other的变量
  2. 检测this与otherObject是否引用同一个对象
    这条语句只是一个优化,用为这种计算比一个一个比较类中的域付出的代价小得多
  3. 检测otherObject是否为null,如果null返回false。这项检测是很必要的
  4. 比较this和otherObject是否属于同一个类。如果equals在每个子类中有所改变,就要使用getclass检测。如果所有子类拥有统一的语句,就使用instanceof检测。
  5. 将otherObject转换为相应的类变量
  6. 现在对所有需要比较的域进行比较,使用==比较基本数据类型,使用equals比较对象域,如果匹配返回true

如果在子类中定义equals那么需要包含super.equals(other)
对于数组类型的域,可以使用Arrays。equals方法检测相应的数组元素是否相等。
hashCode方法
散列码是由对象导出的一个整数值,散列码没有规律,如果两个对象不同,散列码基本不同。由于对象定义在Object中,因此每个对象都有一个默认的散列码,其为对象的储存地址,由Object导出的散列码是其内存地址。如果重新定义equals方法,那么就要重新定义hashCode方法。,以便于将对象插入散列表中。hashCode应该返回一个整型数值,并合理的组合实例域的散列码,以便能够让各个不同的对象产生的散列码更加均匀。使用null安全的方法Object.hanshCode.如果参数为null,那么方法返回0,否则返回对参数调用hashCode的结果,使用静态方法Double.hashCode来避免创建Double对象。需要组合多个散列值时可以调用Object.hash并提供多个参数。这个方法会调用各个参数调用Object.hashCode,并组合这些散列值。equals与hashCode定义方法必须一致,如果equals返回为true,那么hashCode就必须返回相同的值,如果比较雇员的ID,那么hashCode返回散列ID,而不是姓名或储存地址,两个相同的对象,或者意义上相同的对象散列值相同
tostring方法
用于返回表示对象值的字符串,设计子类应该将子类域的描述添加进去。如果使用了getClass().getName().那么子类只需要使用super.toString(),只要对象与一个字符串连接起来,就会自动调用toString方法,以便获得对象字符串的描述。建议为每一个自定义类增加一个toString方法。在调用x.String()的地方可以使用“”+x代替。这条语句将一个空串与x的字符串表示连接,如果x是任意一个对象,并调用ptintln方法就会直接调用x.toString方法,并打印得到的字符串。数组继承了Object的toSring方法,要想打印数组,应该使用Arrays.srting方法。toString是一种实用工具,以便用户获得一些关于对象有用的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值