ADT与OOP中的等价性

在集合论与图论中我们曾经学过,有关等价的定义:应满足自反性,传递性与对称性。

那么对于ADT来说等价性的定义是什么呢:

在软件构造这一课程中,我们学习了两种判定方法,分别是AF方式判定,观察者方式判定

AF方式判定:对于之前博客中提到的的RI中的元素,经过AF映射后得到相同的结果则可判断为等价

观察者方式判定:站在外部观察者的角度,如果两个搞对象调用任何相同的操作,都会得到相同的结果,则认为这两个对象是等价的

如下图题:

在忽略大小写和除去非字符字符串的情况下,找出包含字母相同的集合,在如此AF的要求下,1,2,5号中都包含了a(A),b(B),c(C)

在size()的作用是返回的是集合中不同元素的个数,contains()的作用是通过调用equals()来判断集合中包含哪些元素,length()返回字符串长度,union()是并操作,isAllLower()是判断字母大小写,first()是返回首字母。

contains()单独时对于AF中描述的等价的字符串做出操作后都能得到相同的结果,size()的问题是在不等价的字符串中可能返回相同的结果,如“AC”,“AB”,都会返回2;第三个是可以做到判断等价性的;第四个是length对于AF中要求的等价性相同的字符串会返回不同的值,如“AAA”和“A” 

“==”和equals:

==判断内存地址是否相等;equals是对象等价性

在定义ADT时,需要根据对“等价”的要求,决定是否重写equals()

Object中实现的equals通常不是我们程序所需要的,因此需要进行重写

而在重写时,需要签名与Object中的equals()完全一致,否则会被视为重载,在程序内部对于equals()的调用时发生调用的错误导致程序结果的错误,需要设置@Override来进行签名的检查。

判断下图中最终的打印结果:

最终会打印false;

因为Name类中的equals()的参数类型为Name而非Object,所以编译器会认为这是一个重载,而contains在进行调用时进行判断的依据是调用equals(),而这里面的equals()会进行地址空间的检查,而虽然判断的内容与add内容一致,但是由于是new会新申请一段地址空间,所以会返回false。 

下图的打印结果?

true,由于equals()被重写,equals()判断正常

 一个正确的equals():由于没有AF,所以并不规范

intanceof作为一个操作符,用来判断o是否是PhoneNumber产生的对象,其功能与方法getClass()类似

哈希值,hashCode():

作为一个在数据结构中接触过的概念,java中只有涉及到hashSet等特殊结构时才会牵扯hashCode,平时并不会进行使用。

同一程序多次调用一个对象的hashCode()方法时,应返回相同的值,因为一次执行中,哈希值应该是统一不变的。

但多次执行时,同一对象不需要相同的哈希值。

不同的对象也可以拥有相同的哈希值,但这样做会降低程序性能。

如果仅仅为了简单方便操作考虑,可以给所有对象相同的哈希值,但这样会使程序性能大大降低。

对于可变的数据类型:

对于可变的数据类型来说,等价性的判断通常会变得困难,但也存在一系列标准。

观察等价性:在不改变的状态下,两个可变对象看起来是否一致

行为等价性:调用对象的任何方法都展示出一致结果

对于可变类型,往往倾向于更严格的观察等价性,但有些时候,观察等价性可能产生bug,甚至破坏RI,如对象的哈希值改变后,hashSet不能及时更新哈希桶的位置,导致哈希值找不到对对应元素,目前,这方面的有些问题,一直不能得到有效的解决。

下图题对于可变类型的判断进行了简单的测试,由于比较简单,不进行详细解释 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值