软构复习8 Equality in ADT and OOP (ADT和OOP中的“等价性“)

8 Equality in ADT and OOP (ADT和OOP中的"等价性")

1.Equivalence Relation(等价关系)

ADT是对数据的抽象,体现为一组对数据的操作

AF为抽象函数:内部表示--> 抽象表示

我们可以根据抽象函数AF来定义ADT的等价操作:检查抽象函数是否满足等价关系:自反、对称、 传递。

2.Equality of Immutable Types

  1. a和b是等价的,如果对于抽象函数f(x)有:f(a) =f(b)
  2. 站在观察者的角度:对于两个对象,调用任何相同的操作,都会得到相同的结果,则认为这两个对象是等价的。

例:对于集合{1,2}和{2,1},有操作 cardinality |...|和membership ∈

对于ADT中所有的方法,我们调用任何方法都不能区别。(如果除了构造方法没有别的方法了,那么我们就不可以通过这一条来判断等价)

 例:只有一个构造方法,那么我们就需要通过AF来判断是否等价

        Alphabetic case(字母大小写)、non-letters(非字母)

  1. == 和 equal()

==:对于基本数据类型,判断的是值是否相同。对于引用数据类型,判断的是地址是否相同(是否指向内存中同一块地址)

equal():判断的是对象的等价性。当我们自定义ADT时候,需要重写equals方法。

重写需要@Override注解,不要重载!

例:

为什么d1.equals(d2)为true而d1.equals(o2)为false呐?

因为在Duration中,实际上有两个equals方法

一个为我们上面新加的,另一个为Object类中的equals方法(所有的类均为Obejct的子类)

由于静态类型检查,d1.equals(d2)调用的是我们上面新添加的方法

d1.equals(o2)会因为o2为Object类而调用Object类中的equals方法,实则还是判断地址是否相同。

instanceof关键字:java中的一个双目运算符,可以判断一个对象是否为一个类(或接口、抽象类、父类)的实例,为动态检查

Obj    instanceof   Class :判断Obj是不是xxx的一个实例

使用:1.声明一个Class类的对象,判断obj是否为Calss的实例对象

     2.声明一个Class接口实现类的对象,判断obj是否为Class接口实现类的实例对象

    ArrayList   arrayList = new ArrayList();

    arrayList   instanceof List; //为true

    3.obj为Class的直接或者间接子类

    我们有一个父类Person和继承Person的类Man

注意:obj必须为引用类型,不能为基本类型,否则编译就不会通过

平常我们应该避免使用instanceof,除了再重写equals方法时候。

4.The Object contract

对于equals(),我们必须遵守:

(1).必须符合等价关系

(2).除非对象被修改,否则多次调用equals应该得到同样的结果

(3).“相等的对象”其hashcode()结果也必须一致

5.Equality of Mutable Types

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

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

往往我们更倾向于实现严格的观察等价性。

对于immutable,上述两者是等价的,因为没有 mutator方法

注意:如果某个mutable的对象包含在HashSet集合类中,当其发生改变后,集合类的行为不确定。

例:这是为什么?

一开始,我们的List集合里面只有一个"a",其hashCode我们假设为a

那么会根据其哈希值将其放入一个哈希桶。当list集合添加了一个“b”,那么他的哈希值会改变,不再是a了,但set集合不会因此改变list的哈希桶位置,所以查找就永远不会找到它了。

总结:对于immutable类型,我们要重写equals和hashcode方法

   对于mutable类型,我们不应该重写equals和hashcode,但是java在其集合中并没有遵循这一规则,导致我们上述问题的出现。

6.Autoboxing and equality

   但是x == y 为false(注意Integer的缓存机制-128-127不适用new Integer的情况)

例:输出结果为false

首先put的时候,会把int的130转换为Integer的130,注意这里因为130不在缓存的范围内,所以a和b放入的不是一个Integer对象,所以两者地址不同,返回false

上述这种情况就是true,因为126在缓存机制的范围之内,所以都指向了同一片内存地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值