摘要:即不使用繼承方式,而將父類包含在子類中重寫只有當坐標和顏色都相同才返回當然,重寫的時候一定記得重寫重寫重寫參考文獻第二版第條覆蓋方法時請遵守通用約定
問題復現:
首先有一個Point類,重寫了equals方法:
public class Point{ private final int x; private final int y; public Point(x,y){ this.x=x; this.y=y; } @Override public boolean queals(Object o){ if(!(o instanceof Point){ return false; } Point p = (Point)o; return p.x == x && p.y == y; } }
另有一個擴展類,ColorPoint繼承Point類
public class ColorPoint{ private final Color color; public ColorPoint(int x,int y,Color color){ super(x,y); this.color=color; } }
這時候比較兩個點的時候就有個問題:
Point point = new Point(1, 2); ColorPoint cPoint = new ColorPoint(1, 2, Color.RED); System.out.println(point.equals(cPoint)); // true System.out.println(cPoint.equals(point); // false
可以發現equals方法違背了對稱性原則,原因是Point的equals方法在接收ColorPoint類型的參數時,會將其當做Point進行比較,忽略了顏色的判斷,認定兩個類是相等的。
對此我們做出一些修改:
此時可修改equals方法,加入對顏色的判斷: if(!(o.instanceOf(Point)) return false; //if o is a normal point,ignore color if(!(o.instanceOf(ColorPoint)) return o.equals(this); //if o is a colorPoint .do a full compation return super.equals(o) && ((ColorPoint)o).equals(this.color);
這段代碼修復了違背對稱性的錯誤,但兩個以上的點會有錯誤,比如 兩個ColorPoint和一個Point作比較,如下:
ColorPoint cPointRed = new ColorPoint(1, 2, Color.RED); Point point = new Point(1, 2); ColorPoint cPointBlue = new ColorPoint(1, 2, Color.BLUE); System.out.println(cPointRed.equals(point)); // true System.out.println(point.equals(cPointBlue)); // true System.out.println(cPointRed.equals(cPointBlue)); // false
這樣又違背了傳遞性原則。這時候就有個建議:復合優先于繼承。
即不使用繼承方式,而將"父類"包含在"子類"中
public class ColorPoint{ private final Point point; private final Color color; public ColorPoint(int x,int y,Color color){ point.x = x; point.x = x this.color = color; } public Point getPoint(){ return this.point; } //重寫equals @Override public boolean equals(Object o){ if(!(o instanceof ColorPoint){ return false; } ColorPoint cp = (ColorPoint)o; //只有當坐標和顏色都相同才返回true; return cp.point.equals(this.point) && cp.Color.equals(color); } }
當然,重寫equals的時候一定記得重寫hashCode~重寫hashCode~重寫hashCode~~de~de~de~
參考文獻:《Effective Java》第二版 第8條 “覆蓋equals方法時請遵守通用約定”
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76881.html
摘要:本章中的大部分內容適用于構造函數和方法。第項其他方法優先于序列化第項謹慎地實現接口第項考慮使用自定義的序列化形式第項保護性地編寫方法第項對于實例控制,枚舉類型優先于第項考慮用序列化代理代替序列化實例附錄與第版中項目的對應關系參考文獻 effective-java-third-edition 介紹 Effective Java 第三版全文翻譯,純屬個人業余翻譯,不合理的地方,望指正,感激...
摘要:推薦序前言致謝第一章引言第二章創建和銷毀對象第項用靜態工廠方法代替構造器第項遇到多個構造器參數時要考慮使用構建器第項用私有構造器或者枚舉類型強化屬性第項通過私有構造器強化不可實例化的能力第項優先考慮依賴注入來引用資源第項避免創建不必要的對象 推薦序 前言 致謝 第一章 引言 第二章 創建和銷毀對象 第1項:用靜態工廠方法代替構造器 第2項:遇到多個構造器參數時要考慮使用構建器 第...
摘要:類選擇器具有更高的專用性,所以將戰勝元素選擇器。個位在整個選擇器中每包含一個元素選擇器或偽元素就在該列中加分。選擇器六明顯地輸給了了五,其專用性值為和它在鏈中少了一個元素選擇器。當有多個選擇器作用在一個元素上時,哪個規則最終會應用到元素上? 其實這是通過層疊機制來控制的,這也和樣式繼承(元素從其父元素那里獲得屬性值)有關。 元素的最終樣式可以在多個地方定義,它們以復雜的形式相互影響。這些復雜...
摘要:知道存在是很有用的,這樣當你在別人的代碼中遇到它時,你就知道它是什么了。如上面所示的示例所示,元素選擇器具有很低的特殊性。類選擇器具有更高特殊性,所以將戰勝元素選擇器。個位在整個選擇器中每包含一個元素選擇器或偽元素就在該列中加分。 在實際的工作中,我們可能還有些疑惑,當有多個選擇器作用在一個元素上時,哪個規則最終會應用到元素上?其實這是通過層疊機制來控制的,這也和樣式繼承(元素從其父元...
摘要:來源前條來源一書英文版已經出版,這本書的第二版想必很多人都讀過,號稱四大名著之一,不過第二版年出版,到現在已經將近年的時間,但隨著,,,甚至的發布,語言發生了深刻的變化。譯者在這里第一時間翻譯成中文版。供大家學習分享之用。 來源:sjsdfg/effective-java-3rd-chinese前 51 條來源:Effective Java, Third Edition 《Effec...
閱讀 2836·2021-11-19 09:40
閱讀 3695·2021-11-15 18:10
閱讀 3281·2021-11-11 16:55
閱讀 1231·2021-09-28 09:36
閱讀 1647·2021-09-22 15:52
閱讀 3367·2019-08-30 14:06
閱讀 1160·2019-08-29 13:29
閱讀 2307·2019-08-26 17:04