nudtgk2000 发表于 2013-2-3 11:17:08

走了一段值得的弯路

 
class C {    int i;    String j;    public C(int i, String j) {this.i = i; this.j = j;}    // #1    public boolean equals(Object o) {      if (null == o) return false;      if (o instanceof C) {            C c = (C) o;            return this.i == c.i && this.j.equals(c.j);      }      return false;    }/*    // #2    public boolean equals(C o) {      if (null == o) return false;      return this.i == o.i && this.j.equals(o.j);    } */}class Ce extends C {    int a;    public Ce(int i, String j, int a) {      super(i, j);      this.a = a;    }/*    // #3    public boolean equals(Object o) {      if (null == o) return false;      if (o instanceof Ce) {            Ce c = (Ce) o;            return this.i == c.i && this.j.equals(c.j) && this.a == c.a;      }      return false;    } *//* // #4    public boolean equals(Ce o) {      if (null == o) return false;      return this.i == o.i && this.j.equals(o.j) && this.a = o.a;    }*/}class Cn {    int i;    String j;   public Cn(int i, String j) {this.i = i; this.j = j;}}public class Test {    public static void main(String[] args) {      C o1 = new C(1, "o1");      Ce o2 = new Ce(1, "o1", 2);      Cn o3 = new Cn(1, "o1");      System.out.println(o1.equals(o2));      System.out.println(o2.equals(o1));      System.out.println(o1.equals(o3));    }} 代码#1是马士兵讲重写 equals() 方法时的例程,我当时想按代码#2的方法重写equals方法是否同样成立而且跟简洁呢?因为类型检查的任务推给传参去完成了,#2的方法并不是重写Object类的方法,而是重载,当要比较的对象是本类及其子类实例时会调用这个方法,如果不是则会调用Object类的equals方法(比较引用是否相同,更严苛),这在初步实验中是没有问题的。
但是,当子类照类似的写法 #4 “重写”equals的时候,错误就出现了,原因仍是在于它是重载而非重写。子类重写的意图是不能与父类对象equals,但是#4的写法会在要比较父类对象时“意外地”调用父类的equals方法从而返回true。只有#1和#3的写法才能符合要求。
这条弯路的教训是:看似笨拙的逻辑其实较少歧义,比较健壮,不要一味追求“精巧”的优美,毕竟在实际应用之前测出一个反例是十分困难的。
页: [1]
查看完整版本: 走了一段值得的弯路