ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ADT和OOP中的等价性

2022-06-11 02:00:27  阅读:214  来源: 互联网

标签:ADT 对象 equals 等价 hashCode OOP 方法


  等价性问题:现实世界中的对象实体都是独一无二的,除了是同一个,不可能完全相等。基于 OOP 原则,在软件中,也要考虑这个相等的问题,我们肯定不能说除了同一个,全都不相等,什么情况下两个事物认为是等价的,可相互替代的,即我们要关注的等价性问题。

  等价关系:等价具有自反、对称、传递的性质,我们对等价方法的设计也必须遵守这些性质。

 

  三种认定等价的方式:

1)基于 AF 定义 ADT 的等价操作:如果 AF 将两个对象映射到同样的结果,则这两个对象等价。

2)基于外部观察者角度认定等价性:对于两个对象调用任何相同的操作都得到相同的结果,则认为二者等价。

3)同一个才算是等价:一般是用“==”定义的等价,即引用等价性,只有两个对象在内存中的地址是相同的才会被认定为等价。但注意,“==”对于基本数据类型是直接依据其具体内容是否相同来判断等价的。

  

  对于自己设计的ADT的等价判断方法的实现:

  “==”是直接判断对象的内存地址的,不想如此定义等价就要提供一种单独的方法,也即 equals() 方法。Object 类的 equals() 方法是直接用“==”来判断的,若自己设计 ADT,一般都需要根据自己的需求来重写 equals 方法。注意,是重写 equals() 方法,而非重载。这就需要我们传入的参数是 Object 类,并在 equals() 内多一步判断传入的参数对象是否是你所要判断的类,若是,则将其转换成你所要判断的 ADT 的类,再进行具体内容的比较。下图给出一个按上述格式重写 equals() 方法的例子:

 

   但是,仅仅重写 equals() 方法是不够的!若两个对象“相等”,它还必须要有相同的哈希码,也即hashCode()结果必须相同。这是因为我们设计的 ADT 可能被用于如 hashSet、 hashMap 等类型,在判断等价时,可能会先判断 hashCode() 是否相等,若相等,再在同一个哈希桶中找到对应对象进行比较,否则将直接判断为不等。

  因此,我们若重写了 equals() 方法,也就需要重写 hashCode() 方法。重写 hashCode() 应该注意,返回值应该由我们判断相等时考虑的那些内容的信息构成,就如上图的例子,返回的哈希码应该是和 name.first 和 name.last 有关的一个 int 值,比如返回 17*hashCode(name.first)+hashCode(name.last) 等。

  对于可变数据类型,判断等价性有两种标准:观察等价性和行为等价性。观察等价性即不改变对象的状态对其观察,看是否可以区分,也即对其 creator、producer 和 observer 方法进行测试,不测 mutator 方法;行为等价性则要求在对两个对象改变状态后仍然无法区分,即调用 mutator 方法后,进行别的操作也不会得到不同的结果。可以理解为观察等价性是看当前状态不变时,两个对象是否相等,行为等价性则要求两个对象现在、以后任何时刻,都无法区分。

  注意,对于可变数据类型来说,观察等价性可能导致 bug,甚至破坏 RI,比如对于一个hashSet<List<String>> 对象来说,如果将 list 修改,导致 list 的哈希码发生变化,但是它仍然存在在 set 集合的原来的哈希桶中,即在 set 集合中对应的仍然是原来的哈希码,这时,如果调用 set.contains(list) 将返回 false ,即使 list 的确存在在 set 里(contains方法会调用等价方法来判断是否包含对应对象元素)。

  由于观察等价性的这个问题,对于可变数据类型,我们应该用行为等价性来判断自己设计的 ADT 的对象等价与否,也即只能直接用“==”来判断,所以我们直接继承 Object 的 equals 方法即可。而对于不可变数据类型,其根本没有 mutator,不会改变状态,所以只有观察等价性标准来判断其是否等价,因此需要重写 equals() 方法和 hashCode() 方法。

  

标签:ADT,对象,equals,等价,hashCode,OOP,方法
来源: https://www.cnblogs.com/diguawan/p/16365119.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有