首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

满载equals的方法

2012-12-24 
重载equals的方法很多函数,都要用到实体类的equals方法,比如Map.contains()。第一步 重载equals()Point p

重载equals的方法

很多函数,都要用到实体类的equals方法,比如Map.contains()。


第一步 重载equals()
Point p = new Point(1, 2);ColoredPoint cp = new ColoredPoint(1, 2, Color.INDIGO);Point pAnon = new Point(1, 1) { @Override public int getY() { return 2; }};Set<Point> coll = new java.util.HashSet<Point>();coll.add(p);System.out.println(coll.contains(p)); // 打印 trueSystem.out.println(coll.contains(cp)); // 打印 falseSystem.out.println(coll.contains(pAnon)); // 打印 true

这些例子显示了如果父类在equals的实现定义并调用了canEquals,那么开发人员实现的子类就能决定这个子类是否可以和它父类的实例进行 比较。例如ColoredPoint,因为它以”一个着色点永远不可以等于普通不带颜色的点重载了” canEqual,所以他们就不能比较。但是因为pAnon引用的匿名子类没有重载canEqual,因此它的实例就可以和Point的实例进行对比。

canEqual方法的一个潜在的争论是它是否违背了Liskov替换准则(LSP)。例如,通过比较运行态的类来实现的比较技术(译者注:?canEqual的前一版本,使用.getClass()的那个版本),将导致不能定义出一个子类,这个子类的实例可以和其父类进行比较,因此就违背了 LSP。这是因为,LSP原则是这样的,在任何你能使用父类的地方你都可以使用子类去替换它。在之前例子中,虽然cp的x,y坐标匹配那些在集合中的点, 然而”coll.contains(cp)”仍然返回false,这看起来似乎违背得了LSP准则,因为你不能这里能使用Point的地方使用一个 ColoredPointed。但是我们认为这种解释是错误的,因为LSP原则并没有要求子类和父类的行为一致,而仅要求其行为能一种方式满足父类的规 范。

通过比较运行态的类来编写equals方法(译者注:?canEqual的前一版本,使用.getClass()的那个版本)的问题并不是违背LSP准则的问题,但是它也没有为你指明一种创建派生类的实例能和 父类实例进行对比的的方法。例如,我们使用这种运行态比较的技术在之前的”coll.contains(pAnon)”将会返回false,并且这并不是 我们希望的。相反我们希望“coll.contains(cp)”返回false,因为通过在ColoredPoint中重载的equals,我基本上可 以说,一个在坐标1,2上着色点和一个坐标1,2上的普通点并不是一回事。然而,在最后的例子中,我们能传递Point两种不同的子类实例到集合中 contains方法,并且我们能得到两个不同的答案,并且这两个答案都正确。

–全文完–



热点排行