我有一個接口,我希望實現此接口的每個人都實現一個覆蓋「equals」方法。在接口中強制執行「等於」
有沒有辦法確保發生?
我想這會發生的方式是,實現我的接口的類將自動從Object中獲取equals,因此使接口很高興。
我有一個接口,我希望實現此接口的每個人都實現一個覆蓋「equals」方法。在接口中強制執行「等於」
有沒有辦法確保發生?
我想這會發生的方式是,實現我的接口的類將自動從Object中獲取equals,因此使接口很高興。
沒有,你只可以創造的,而不是像這樣的接口的抽象類:
public abstract class MyApi {
public final boolean equals(Object other) {
if (other == this) {
return true;
}
if (other instanceof MyApi) {
return equals((MyApi)other);
}
return false;
}
protected abstract boolean equals(MyApi other);
}
或者更簡單的版本:
public abstract class MyApi {
public boolean equals(Object other) {
throw new UnsupportedOperationException("equals() not overridden: " + getClass());
}
}
編輯(給它後一試來自@CodeConfident的評論,謝謝!永遠不會假定它會起作用):
您也可以簡單地在ab中聲明equals()
加強海峽類(!不是一個接口),因此隱藏Object
實施和任何子類強制執行新的實現:
public abstract class MyApi {
public abstract boolean equals(Object obj);
public abstract int hashCode();
}
反正你應該始終貫徹equals()
和hashCode()
一起履行合同。
如果您主張使用抽象類,爲什麼不聲明equals(Object)是抽象的? – ILMTitan 2010-06-10 14:33:08
@ilmtitan:你不能聲明一個繼承的方法摘要! – 2010-06-10 17:39:39
@ArneBurmeister - 這是不正確的(現在至少)。您絕對可以在抽象類中使用抽象方法重寫繼承的方法。看到這個答案︰https://stackoverflow.com/questions/1718112/tostring-equals-and-hashcode-in-an-interface#answer-1718170 – AjahnCharles 2017-07-20 07:08:42
不可以。您可以將它添加到接口(以及javadocs),但是如果Object.equals具有相同的簽名,則不能讓編譯器使它們覆蓋它。
編輯:可能不是一個好主意(請參閱FarmBoy的評論)。留在這裏爲後人。
而不是使用Object
類中的equals(Object obj)
,使它們與接口的實現進行比較。
public interface MyInterface {
public boolean equals(MyInterface mi);
}
因此,
public class MyImplementation implements MyInterface {
public boolean equals(MyInterface mi)
{
if(this == mi)
return true;
// for example, let's say that each implementation
// is like a snowflake...(or something)
return false;
}
}
然後:
public class Main {
public static void main(String[] args)
{
Object o = new MyImplementation();
MyImplementation mi1 = new MyImplementation();
MyImplementation mi2 = new MyImplementation();
// uses Object.equals(Object)
o.equals(mi1);
// uses MyImplementation.equals(MyInterface)
mi1.equals(mi2);
// uses Object.equals(Object)
mi2.equals(o);
}
}
這不是一個好主意。任何調用相等的東西(比如把一個對象放到一個'Set'中不會調用這個等於,而是'真正'),所以你會迫使實現類實現這個方法,任何好的程序員都會實現'真正'的 – 2010-06-10 06:35:09
好點 - 我沒有想過這個問題,我想從提問者那裏得到更多關於這個問題背後動機的細節。 – Catchwa 2010-06-10 06:39:37
我猜有可能是爲什麼方法可能需要
希望這樣的等於兩個原因確保所有的課程你的應用程序(或其子集)「將」具有equals方法。就像標準執行一樣,或者確保你使用的某些API能夠正常工作(並且他們期望等於正確實現)。假設你使用Maps的次數很多,並且希望絕對確定一些類的子集絕對可能映射鑰匙) 如果是這樣,這不是要走的路。在這種情況下,你將無法做到這一點,但即使你是這樣,也是不正確的。您應該使用代碼覆蓋工具,並進行更好的單元測試。
你不想要等於方法,但想要一個類似的方法。在這種情況下,您可以在界面中創建另一個具有相似名稱的方法。
的接口是低保方法存在合同。
沒有強制執行該方法的機制應該在接口中被覆蓋。
我已經嘗試在JavaDoc中編寫equals
所需的合同。但hashCode
與equals
一致的要求導致hashCode
的複雜合同。所以我放棄了,用兩個方法的final
實現來創建抽象基類。
你對此的理由是什麼? – 2010-06-10 06:44:40
遇到這個問題時遇到的具體情況; 我有一個接口,實現了幾個類。這些類是由唯一的標識符標識的。所以如果兩個標識符是相同的,則應該認爲這些對象是平等的。 有一次,我有一個這些類的列表,並想知道如果一個新的對象已經存在於列表中。 我認爲這將是優雅的List.contains(..)用於此檢查。但是這要求我可以肯定等於被覆蓋。 雖然易於以其他方式解決。抽象類也可以運行得很好。 – Fredrik 2010-06-10 11:06:05