ADT和OOP中的等價性
- 前言
- 引用等價性
- 對象等價性
-
- equals()函數
- hashcode()函數
- 觀察等價性
- 行為等價性
- 總結
前言
等價性的劃分:
不可變對象的引用等價性==和對象等價性equals()
可變對象的觀察等價性和行為等價性
引用等價性
== 操作符比較引用。
它測試引用相等。兩個引用是 == 如果它們指向記憶體中的相同存儲。在快照圖中,如果兩個引用的箭頭指向同一個對象氣泡,則它們為==。
== 對基本資料類型,使用== 判定相等
對象等價性
equals()函數
equals()操作比較對象内容——換句話說,對象相等。
對對象類型,使用equals()
正常的equals()方法:在Object 中實作的預設equals() 是在判斷引用等價性,是以應該重寫equals()方法
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL0MGRPhXRE50MRpHW3BjMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzIjNxMjNyYTMyAzNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
錯誤重寫:這是Overload,不是重寫
正确重寫:
一個更好的方法去實作equals()
hashcode()函數
等價的對象必須有相同的hashCode
根據上面描述的Duration類,在修改equals()函數之後,d1.equals(d2)=true,但是輸出hashCode()的值發現兩者的哈希值不同
修改方法:為對象的每個元件計算一個散列代碼,用于确定是否相等(通常通過調用每個元件的hashCode方法),然後組合這些散列代碼,并進行一些算術操作。
對于Duration,這很容易,因為類的抽象值已經是一個整數值:
觀察等價性
當不能通過不改變對象狀态的觀察來區分它們時,也就是說,隻調用observer、producer和creator方法。這通常被嚴格地稱為觀察等價性,因為它測試兩個對象在程式的目前狀态下是否“看起來”相同。
觀察等價性:在不改變狀态的情況下,兩個mutable對象是否看起來一緻
對可變類型來說,往往傾向于實作嚴格的觀察等價性
實作觀察等價性的缺陷:
行為等價性
當它們不能通過任何觀察來區分時,甚至狀态也會改變。這種解釋允許調用兩個對象上的任何方法,包括mutators。這被稱為行為平等,因為它測試兩個物體在目前狀态和所有未來狀态下是否會“表現”相同。
行為等價性:調用對象的任何方法都展示出一緻的結果
對可變類型,實作行為等價性即可。也就是說,隻有指向同樣記憶體空間的objects,才是相等的。是以對可變類型來說,無需重寫equals() and hashCode()這兩個函數,直接繼承Object 的兩個方法即可。如果一定要判斷兩個可變對象看起來是否一緻,最好定義一個新的方法。
總結
1.對于不可變對象:
equals()應該比較抽象值。這就相當于說equals()應該提供行為平等。
hashCode()應該将抽象值映射為整數。
是以,不可變類型必須重寫equals()和hashcode()函數
2.對于可變對象:
equals()應該比較引用,就像==一樣。同樣,這就相當于說equals()應該提供行為平等。
hashCode()應該将引用映射為一個整數。
是以,可變類型不需要重寫equals()和hashcode()函數