软件构造学习(三)ADT与OOP的等价性
这次记录的主要内容是围绕软件构造中有关抽象数据型的知识点。ADT可以大致分为Immutable类型的类和mutable类型的类,可以将ADT的等价性分为两部分,第一部分是Immutable类的等价性,第二部分是mutable类型的类的相关等价性。
一、不可变类型的等价性。
1.利用AF和观察者等价性判相等
- 判断不可变类型等价性的第一种方法是利用AF,AF映射到同样的结果则等价。也就是说如果R空间的两个对象对应A空间的同一个对象则我们称这两个R空间的对象是等价的。
- 第二种判相等的方法是观察者等价性,即在外部观察者角度:对两个对象调用任何相同的操作,都会得到相同的结果,则认为这两个对象是等价的。
下面来针对上面两个方法来分析一个例子,根据下面代码,判断这五个对象是否相等:

先来用AF判相等,ADT的AF写道忽略字母情况和非字母的,所以根据这个映射关系,第一个、第二个和第五个是等价的。如果考虑观察者等价性,我们查看ADT的方法可以发现,这个类只有constructor没有observer,所以这个类的任何两个对象都具有观察者等价性,也就是我们无法利用观察者等价性。
2. ==和equals()
==指引用相等,对于对象数据类型,只有在左右两边指向同一个对象时,才会判断为相等返回true,是一种很严格的相等。通常使用==来判断基本数据类型是否相等。而equals()是对象相等,在Object中实现的缺省equals()是在判断引用等价性,但这通常不是我们所期望的,因此常常将其重写。看下面这个例子:

此处不属于重写,而是重载。因为方法重写的两个方法返回值、方法名、参数列表必须完全一致,而此处的参数发生了变化,因此是重载。
再看下面这两个equals()的输出结果:

第一个结果应该是true,因为d1和d2都是Duration类型,在类型中已实现了equals()的重写,因此静态检测时可以检测到它们是Duration类型,从而调用Duration中的euqals()方法。而o2的类型是object,所以会调用object的equals()方法,也就是判断引用等价,所以返回结果是false。
object的equals()方法有如下规约:
1.满足自反、传递、对称;
2.除非对象被修改了,否则调用多次的equals()方法应当一致;
3.obj.equals(null);应当返回为false;
4.判断相等的对象,其hashCode()的结果必须一致。
所以如果重写equals(),就必须重写hashcode(),除非能够保证自定义的ADT是永远不会被放入到Hash类型的集合中,但是这个条件难以满足。
二、可变类型等价性
1.行为等价性和观察等价性
- 观察等价性是指在不改变状态的情况下,两个mutable对象是否看起来一致
- 行为等价性是指调用对象的任何方法都展示出一致的结果。当两个对象无法通过任何观察,甚至状态变化来区分时。就会对这两个对象调用任何方法,包括mutators。这被称为行为等价性,因为它测试两个对象在当前和未来的所有状态下是否“行为”相同。(注:对于不可变类型来说,行为等价性和观察者等价性等价,因为不可变类型不包括mutator方法)
浙公网安备 33010602011771号