子父类覆盖方法和实现接口时牵扯到的细节问题。

  最近在看core Java,里面涉及到的对于编写equals方法以及继承时,可能会发生的错误做出了详细的介绍,看完后觉得有点意外,因为在看教学视频时,并没有涉及到如此多的重点,现在将要点提取出来整理如下:

  Java语言对于equals方法的要求如下:

    △自反性:对于任何非空引用x,x.equals(x)应该返回true

    △对称性:对于任何引用x和y,当且仅当x.equals(y)返回true,y.equals(x)也可以返回true.

    △传递性:对于任何引用x,y和z,x.equals(y)返回true,y.equals(z)返回ture,那么x.equals(z)返回true.

    △一致性:如果x和y引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果.

    △x.equals(null)应当返回false.

  一个正确严谨的equals方法应该满足以上五个特性,那么可以从两个情况进行分析:

  1).如果子类能够拥有自己相等的概念,则对称性要求强制采用getClass进行检测

  2).如果由超类决定相等的概念,那么可以使用instanceOf进行检测,这样可以在不同子类对象之间进行相等的比较,同时将超类的equals方法设置为final.

  现在用两个小事例说明一下观点:

  1)子类可以拥有自己的新特性时,父类equals方法的编写,这里子类复写的方法几乎完全相同,在此省略、另外为了代码简洁,没有重写get,set方法。

  

//演示子类可以拥有自己的特性存在时候equals方法的编写
class Car {
    private String name;
    private int color;
    public Car(String name, int color) {
        super();
        this.name = name;
        this.color = color;
    }
    @Override
    public int hashCode() {
        return Objects.hash(name,color);    //根据Java7新特性,便捷的复写hashcode方法.
    }
    @Override
    public boolean equals(Object obj) {
        if(obj==null)    return false;    //x.equals(null)需要返回false
        if(this==obj)    return true;    //x.equals(x)需要返回true
        if(this.getClass()!=obj.getClass())        return false;//不是同一个类的对象,返回false
        //此时确定obj和this是同一个运行时对象.
        Car other=(Car)obj;
        return this.name.equals(other.name)&&this.color==other.color;
    }    
}

  2)由超类决定相等的概念的情况下,equals方法的复写。

  

//演示超类决定相等概念的时候equals方法的编写
class Car {
    private String name;
    private int color;
    public Car(String name, int color) {
        super();
        this.name = name;
        this.color = color;
        
    }
    @Override
    public int hashCode() {
        return Objects.hash(name,color);    //根据Java7新特性,便捷的复写hashcode方法.
    }
    @Override
    public final boolean equals(Object obj) {
        if(obj==null)    return false;    //x.equals(null)需要返回false
        if(this==obj)    return true;    //x.equals(x)需要返回true
        if(obj    instanceof Car)        return false;//超类不是Car,返回false
        //此时确定obj和this是同一个超类.
        Car other=(Car)obj;
        return this.name.equals(other.name)&&this.color==other.color;
    }    
}

 

posted @ 2016-06-11 10:51  hlhdidi  阅读(594)  评论(0编辑  收藏  举报