天天看點

軟體構造筆記(十二)---PPT第八講前言引用等價性對象等價性觀察等價性行為等價性總結

ADT和OOP中的等價性

  • 前言
  • 引用等價性
  • 對象等價性
    • equals()函數
    • hashcode()函數
  • 觀察等價性
  • 行為等價性
  • 總結

前言

等價性的劃分:

不可變對象的引用等價性==和對象等價性equals()

可變對象的觀察等價性和行為等價性

引用等價性

== 操作符比較引用。

它測試引用相等。兩個引用是 == 如果它們指向記憶體中的相同存儲。在快照圖中,如果兩個引用的箭頭指向同一個對象氣泡,則它們為==。

== 對基本資料類型,使用== 判定相等

對象等價性

equals()函數

equals()操作比較對象内容——換句話說,對象相等。

對對象類型,使用equals()

正常的equals()方法:在Object 中實作的預設equals() 是在判斷引用等價性,是以應該重寫equals()方法

軟體構造筆記(十二)---PPT第八講前言引用等價性對象等價性觀察等價性行為等價性總結

錯誤重寫:這是Overload,不是重寫

軟體構造筆記(十二)---PPT第八講前言引用等價性對象等價性觀察等價性行為等價性總結

正确重寫:

軟體構造筆記(十二)---PPT第八講前言引用等價性對象等價性觀察等價性行為等價性總結

一個更好的方法去實作equals()

軟體構造筆記(十二)---PPT第八講前言引用等價性對象等價性觀察等價性行為等價性總結

hashcode()函數

等價的對象必須有相同的hashCode

根據上面描述的Duration類,在修改equals()函數之後,d1.equals(d2)=true,但是輸出hashCode()的值發現兩者的哈希值不同

軟體構造筆記(十二)---PPT第八講前言引用等價性對象等價性觀察等價性行為等價性總結

修改方法:為對象的每個元件計算一個散列代碼,用于确定是否相等(通常通過調用每個元件的hashCode方法),然後組合這些散列代碼,并進行一些算術操作。

對于Duration,這很容易,因為類的抽象值已經是一個整數值:

軟體構造筆記(十二)---PPT第八講前言引用等價性對象等價性觀察等價性行為等價性總結

觀察等價性

當不能通過不改變對象狀态的觀察來區分它們時,也就是說,隻調用observer、producer和creator方法。這通常被嚴格地稱為觀察等價性,因為它測試兩個對象在程式的目前狀态下是否“看起來”相同。

觀察等價性:在不改變狀态的情況下,兩個mutable對象是否看起來一緻

對可變類型來說,往往傾向于實作嚴格的觀察等價性

實作觀察等價性的缺陷:

軟體構造筆記(十二)---PPT第八講前言引用等價性對象等價性觀察等價性行為等價性總結

行為等價性

當它們不能通過任何觀察來區分時,甚至狀态也會改變。這種解釋允許調用兩個對象上的任何方法,包括mutators。這被稱為行為平等,因為它測試兩個物體在目前狀态和所有未來狀态下是否會“表現”相同。

行為等價性:調用對象的任何方法都展示出一緻的結果

對可變類型,實作行為等價性即可。也就是說,隻有指向同樣記憶體空間的objects,才是相等的。是以對可變類型來說,無需重寫equals() and hashCode()這兩個函數,直接繼承Object 的兩個方法即可。如果一定要判斷兩個可變對象看起來是否一緻,最好定義一個新的方法。

總結

1.對于不可變對象:

equals()應該比較抽象值。這就相當于說equals()應該提供行為平等。

hashCode()應該将抽象值映射為整數。

是以,不可變類型必須重寫equals()和hashcode()函數

2.對于可變對象:

equals()應該比較引用,就像==一樣。同樣,這就相當于說equals()應該提供行為平等。

hashCode()應該将引用映射為一個整數。

是以,可變類型不需要重寫equals()和hashcode()函數