ADT和OOP中的“等价性”
目 录
- 等价关系
- 一个等价关系是具有下面这些属性的笛卡尔积:
- 对于像==或 equals()这样的布尔值二进制操作,等价性E是该操作返回true的(x、y)的集合。
- 不可变类型的等价性
- 利用AF定义等价性:AF映射到同样的结果,则等价,例如,a等于b当且仅当f(a)=f(b)
- 用观察方法定义等价性:我们谈论抽象值之间平等的另一种方式是外部(客户)能观察到它们的情况。我们可以说,当两个对象不能被观察来区分时,它们是相等的——我们可以应用的每个操作都会对这两个对象产生相同的结果
- ==和.equals()
- ==引用等价性:它测试参考相等式。如果两个引用指向内存中的同一存储器,则它们是==。如果两个引用的箭头指向同一对象气泡,则为==。对于基本类型,使用==判断相等。
- equals()对象等价性:比较对象内容——换句话说,对象相等。对于对象类型,使用equals()。
- 必须为每个抽象数据类型适当地定义等于操作,在自定义ADT时,需要重写Object的equals()。如果用==,是在判断两个
- 实现equals()
- 不是重载,是重写。
- instanceof:测试一个对象是否是一个确定类的实例,使用instanceof是一个动态类型检查而不是静态的,一般来说在面向对象编程中使用instanceof是不好的,除了实现等价性之外的任何地方都不应该使用。
- 哈希表:哈希表是映射的一种表示形式:将键映射到值的抽象数据类型。它包含一个数组,它被初始化为与我们希望插入的元素数量相对应的大小。当键和值进行插入时,我们计算键的哈希码,并将其转换为数组范围内的索引(如通过模)。然后系统会将该值插入到该索引中。哈希表的rep不变量包含一个基本约束,即键位于由其哈希代码确定的槽中。
- 哈希码契约:如果两个对象根据方法相等了,那么他们就必须有相同的HashCode。
不相等的对象,也可以映射为同样的hashCode,但性能会变差。
- 对象契约
- 等价关系:必须定义一个等价关系,即自反的、对称的和传递的关系,除非对象被修改了,否则调用多次equals应同样的结果,
- 非空引用x,x.equals(null)应返回false
- hashCode()必须为被相等方法认为相等的两个对象生成相同的结果。
- 可变类的等价关系
- 观察等价性:在不改变状态的情况下,两个mutable对象是否看起来一致。但在有些时候,观察等价性可能导致bug,甚至可能破坏RI。
- 行为等价性:调用对象的任何方法都展示出一致的结果。
- 对可变类型来说,往往倾向于实现严格的观察等价性。
- 自动封装和等价性
- 自带封装(对象类型)的类型,如int的Integer,比较时int是==,Integer是equals