我無權訪問基類代碼。但是需要能夠在子類中定義equals,並考慮一些基類屬性。基類不定義等於但子類需要。如何實施?
此外,基類沒有受保護的字段。所有字段只能通過訪問器/增變器訪問。
在我的子類中對基類字段進行比較是否會被認爲是不好的?爲什麼?
我需要這樣做,因爲我的基類有一個默認的平等是不適合我的目的工作,但它也有需要做一個子類的equals時要考慮的領域......
我無權訪問基類代碼。但是需要能夠在子類中定義equals,並考慮一些基類屬性。基類不定義等於但子類需要。如何實施?
此外,基類沒有受保護的字段。所有字段只能通過訪問器/增變器訪問。
在我的子類中對基類字段進行比較是否會被認爲是不好的?爲什麼?
我需要這樣做,因爲我的基類有一個默認的平等是不適合我的目的工作,但它也有需要做一個子類的equals時要考慮的領域......
是的,你可以做到這一點,就不會有調用超類的干將任何問題,因爲你能確定的平等任何你想要的,只要你按照合同:
自反:X。等於(x)應該返回true。
對稱:x.equals(Y)== y.equals(x)的
傳遞:x.equals(y)的& & y.equals(Z)=> x.equals( Z)
一致:x.equals(Y)的多次調用,除非X或Y爲調用之間突變始終返回true或false。
而且等號哈希碼的合同:
相等的對象必須有相同的哈希碼
http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#equals(java.lang.Object)
這是完全合理的。在比較派生類時考慮從基類繼承的屬性沒有任何問題。從本質上講,當你比較兩個對象時,所有重要的是根據你選擇的定義是否相同,而不管比較信息來自何處。使用任何你需要的。
應該沒有問題,前提是您也覆蓋hashCode()
,並且提供的問題屬性爲不可變。
的equals()
方法,有時返回true,有時返回false,這取決於是否有人呼籲在平均時間setXXX()
,是很危險的事情 - 它不能被用於許多事情equals()
是良好的,如確定集合中的成員資格。
如果equals()
真的是你需要的東西 - 爲了與其他的API來工作像java.util.Collections
- 那麼我建議重寫存取器扔UnsupportedOperationException
。否則,您的equals()
方法將不可靠。例如見:How to use two numbers as a Map key
如果您不能 - 例如如果mutators是final
- 那麼我甚至不會嘗試子類化。相反,我會將來自'超類'對象的值複製到我自己的字段中,然後將原件丟棄。 (如果你把它周圍,甚至作爲一個私有字段,你不能指望別人沒有對它的引用和變異它。)如果你需要你的「子」與需要的「超」的API進行互操作,然後包括一個即時生成「超類」對象的方法。否則,如果您只是需要爲您自己的目的確定相等性,則根本不會覆蓋equals()
/hashCode()
,而是創建一個新方法,並將其稱爲isEquivalentTo()
。
沒有什麼特別不妥壓倒一切平等的,肯定沒有錯,通過他們的干將訪問私有方法,如果這是你需要做什麼。
但是這裏有一個輕微的概念性的問題,涉及到的里氏替換原則,其中規定,你應該能夠替代一個子類的基類,並沒有得到行爲的任何觀念的轉變。
如果equals()方法要實現是概念從基類中實現了equals很大的不同,然後用你的代碼(如維護)的人會發現很難理解。他們將根據某些假設進行編碼,這些假設會變成錯誤的。例如,如果基本的equals()是基於引用相等,即
equals(Object o) { return this == o;}
和您的實現並不非常不同的東西,用戶需要知道的比他們應該更多有關具體implemntation。它也將違反symmetricality:x.equals(Y)不會是一樣y.equals(x)如果x是你的子類和y的基類。
話雖這麼說,這些都不是不可逾越的,如果你不能改變基部您可能沒有選擇。給你的班級添加很多評論。
關於對稱性:當另一個對象也是你的子類的對象時,你應該確信你的新的equals方法只返回true。 –
可以放鬆*是不可變的*有點*在用作HashMap *中的鍵時不會發生變異,但是您確實應該確保記錄這一點(最好在API中爲equals,hashCode和增變器方法)。 –
就個人而言,我對文檔在這種情況下防止擰緊的能力持懷疑態度,但YMMV。 –