博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
覆盖equals时请遵守通用约定
阅读量:5166 次
发布时间:2019-06-13

本文共 3330 字,大约阅读时间需要 11 分钟。

不覆盖equals方法,在这种情况下,类的每个实例都只与它自身相等,如果满足了一下任何一个条件,这就正是所期望的结果 类的每个实例本质上都是唯一的 不关心类是否提供了“逻辑相等”的测试功能 超类已经覆盖了equals,从超类继承过来的行为对于子类也是合适的。 类是私有的或是包级私有的,可以确定他的equals方法永远不会被调用。这时,应该覆盖equals方法,以防它被意外调用 @override public boolean equals(Object o){
throw new AssertionError();//Mehtod is never called } 如果类具有自己特有的“逻辑相等”概念(不同于对象等同的概念),而且超类还没有覆盖equals以实现期望的行为,这时就需要覆盖equals方法。 这通常属于“值类”的情形。有一种”值类“不需要覆盖equals方法,即用实例受控确保“每个值至多只存在一个对象”的类。 对于这样的类,逻辑相同与对象等同是一回事。因此Object的equals方法等同于逻辑意义上的equals方法 枚举就属于这种类 在覆盖equals方法时,必须遵守下面的约定: equals方法实现了等价关系: 1:自反性 对于任何非null的引用值x,x.equals(x)必须返回true 2:对称性 3:传递性 4:一致性 未修改对象的情况下,多次调用返回结果一样 对于任何非null的引用值x,x.equals(null)必须返回false */ class Point{
private final int x; private final int y; public Point(int x, int y){
this.x = x; this.y = y; } @Override public boolean equals(Object o){
if (!(o instanceof Point)) return false; Point p = (Point)o; return p.x == this.x && p.y == this.y; } //Remainder omitted } //假设需要扩展这个类,为一个点添加颜色信息: class ColorPoint extends Point{
private final Color color; public ColorPoint(int x, int y, Color color){
super(x,y); this.color = color; } // @Override // public boolean equals(Object o) {//这样会失去对称性 // if (!(o instanceof ColorPoint)) // return false; // return super.equals(o) && ((ColorPoint)o).color == color; // } //Point p = new Point(1,2); //ColorPoint cp = new ColorPoint(1,2,Color.RED); //p.equals(cp); true cp.equals(p); false @Override public boolean equals(Object o) {//这样会失去传递性 if (!(o instanceof Point)) return false; if (!(o instanceof ColorPoint)) return false; return super.equals(o) && ((ColorPoint)o).color == color; } //ColorPoint p1 = new ColorPoint(1,2,Color.RED); //Point p2 = new Point(1,2); //ColorPoint p3 = new ColorPoint(1,2,Color.BLUE); //p1.equals(p2); true p2.equals(p3); true p1.equals(p3) false //Remainder omitted } //上面例子结论:我门无法在扩展可实例化的类的同时,既增加新的值组件,同时又保留equals约定,除非愿意放弃面向对象的抽象所带来的优势 //里氏替换原则认为,一个类型的任何重要属性也将适用于他的子类型,因为该类型编写的任何方法,在它的子类型上也应该同样运行的很好 //虽然没有一种令人满意的方法既可以扩展可实例化类,又增加组件,但还是有一种不错的权宜之计。根据第16条建议:复合优先于继承。 //我们不再让ColorPoint扩展Point,而是在ColorPoint中加入一个私有的Point域,以及一个共有的视图方法, // 此方法返回一个于该有色点处在相同位置的普通Point对象 class ColorPoint_Change{
private final Point point; private final Color color; public ColorPoint_Change(int x, int y, Color color){
if (color == null) throw new NullPointerException(); point = new Point(x, y); this.color = color; } /* returns the point-view of this color point */ public Point asPoint(){
return point; } @Override public boolean equals(Object obj) {
if (!(obj instanceof ColorPoint_Change)) return false; ColorPoint_Change cp = (ColorPoint_Change)obj; return cp.point.equals(point) && cp.color.equals(color); } } //注意:可以在一个抽象类的子类中增加新的值组件,而不会违反equals约定 //域的比较顺序可能会影响到equals方法的性能。为了获得最佳的性能,应该最先比较最有可能不一致的域,或者开销最低的域, // 最理想的情况是两个条件同时满足的域。 //覆盖equals方法时总要覆盖hashCode //不要企图让equals方法过于智能 //不要将equals声明中的Object对象替换为其他的类型,@Override注解的用法可以防止犯这种错误

转载于:https://www.cnblogs.com/xcyz/p/7650903.html

你可能感兴趣的文章
Day03:Selenium,BeautifulSoup4
查看>>
awk变量
查看>>
mysql_对于DQL 的简单举例
查看>>
35. Search Insert Position(C++)
查看>>
[毕业生的商业软件开发之路]C#异常处理
查看>>
有关快速幂取模
查看>>
字符串的查找删除
查看>>
NOI2018垫底记
查看>>
Hive(7)-基本查询语句
查看>>
注意java的对象引用
查看>>
C++ 面向对象 类成员函数this指针
查看>>
NSPredicate的使用,超级强大
查看>>
自动分割mp3等音频视频文件的脚本
查看>>
判断字符串是否为空的注意事项
查看>>
布兰诗歌
查看>>
js编码
查看>>
Pycharm Error loading package list:Status: 403错误解决方法
查看>>
steps/train_sat.sh
查看>>
转:Linux设备树(Device Tree)机制
查看>>
iOS 组件化
查看>>