黑马程序员技术交流社区

标题: 讨论一个基础问题,父类对象和子类对象之间究竟能否equal [打印本页]

作者: lvwenwen88    时间: 2011-12-30 22:20
标题: 讨论一个基础问题,父类对象和子类对象之间究竟能否equal
本帖最后由 lvwenwen88 于 2012-1-4 11:19 编辑

讨论一个基础问题,父类对象和子类对象之间究竟能否equal
作者: 房宝彬    时间: 2011-12-30 22:30
这个要是对权限模块非常的了解,你会知道经理和职员是不一样的,只是为了面向对象,所以有了经理继承职员这一现象。 我觉得这个要取决于实际的业务,不能一概而论
作者: 杨丹丹    时间: 2011-12-30 23:17
理论上,根据equal的规则.是不可以的.
因为:a.eq(b)为true时,b.eq(a)也必须为true.
但是,你可以重写equal,这就是你自己的事了.
作者: 林晓波    时间: 2011-12-30 23:48
class Student{
    protect int Id;
    protect String name;
    protect int score;

    public Student(int Id,String name,int score){
        this.Id = Id;
        this.name = name;
        this.score = score
    }
    public boolean equals(Student other){
        if(this.Id == other.Id){
            return true;
        }
        return false;
    }
}
如果有一个Student的子类:
class Cadre extends Student{
    protect String duty;
}
在Student类中,我们认为只要2个Student的对象的Id相等它们就相等,而Cadre是Student的一个子类,在多态的定义中,可以将子类对象的引用赋给父类,我们同样可以将子类对象与父类对象进行比较,由于在Student的equals方法中,只要一个Student类的对象与Cadre类的对象的Id相等,就认为它们相等,同样可以把个相等的概念应用到它的子类,事实上Cadre类从Student继承来的equals方法就可以帮我们完成比较了。

在进行子类对象与父类对象比较的时候,常常遇到另一种情况:
class Student{
    protect int Id;
    protect String name;
    protect int score;

    public boolean equals(Student other){
        if(this.Id == other.Id && this.score == this.score && this.name.equals(other.name)){
            return true;
        }
        return false;
    }
}
如果它同样有一个子类:
class Cadre extends Student{
    protect String duty;
}
在父类中,相等的概念是对象的每个属性都相等,将这个概念扩展到子类,Cadre类可以修该为
class Cadre extends Student{
    protect String duty;

    public Cadre(int Id,String name,int score,String duty){
        super(Id,name,score);
        this.duty = duty;
    }
    public boolean equals(Student other){
       if(super(other) == true && this.duty == other.duty){
           return true;
       }
       return false;
   }
}
在这中情况下我们可能会遇到一中非常有趣的现象:
Student stu1 = new Student(1,"zhanghua",90);
Cadre stu2 = new Cadre(1,"zhanghua",90,"monitoer");
System.out.println(stu1.equals(stu2));
System.out.println(stu2.equals(stu1));
程序运行后打印出一个true一个false,即是stu1与stu2比较是相等的,而stu2与stu1比较是不相等的,然而,根据相等概念的自反性,我们要求x.equals(y)的值应当与y.equals(x)的值一致,在这种请况下,我们要先检查比较的两个对象的类型是否一致,不一致就直接返回false,将Student类中的equals改为:
public boolean equals(Student other){

    if(this.getClass() != other.getClass()){
        return false;
    }
    if(this.Id == other.Id && this.score == this.score && this.name.equals(other.name)){
        return true;
    }
    return false;
}


作者: 为梦而战    时间: 2011-12-31 00:09
     可以先这样理解:子类为什么继承父类?是因为子类中要用的一些功能,父类已经现实了,为了提高功能复用性,就把父类中已有的功能继承过来,但是子类应该还有自己特有的功能,要是和父类功能一样了,那还要去继承,也就多余了。基于这样的理解,那应该明白,子类对象和父类对象还是不一样的。记得重写equals()方法时,也是有个判断的,比如:if(a instanceOf A),如果a不是类A的对象,就不用再比了。那子类对象不是父类的实例,所以即使用equals()去比,也会返回false.
作者: 李盈科    时间: 2011-12-31 17:31
如果是比较对象的话 父类对象和子类对象euqals 是不等的 如果比较内容的话 看具体内容 还是得看你的equals 怎么重写的
作者: 马新乐    时间: 2011-12-31 23:54
equals方法是根据业务情况判断在什么情况下是相等的,这个是由你自由发挥的
一般来说不管员工是什么职位,都有一个员工id标识的,判断多层阶的人是不是一个人都应该用id去判断吧

public class Employee{
  private int employeeId;
  public int getEmployeeId(){
  return employeeId;
}
  public boolean equals(Object obj){
    if (obj == null || !obj instanceof Employee) return false;
    Employee e = (Employee)obj;
    return employeeId == e.getEmployeeId();
  }
}

public class Manager extends Employee{
}

这样不管什么样的情况比较都不会出错的
作者: 陈丹阳    时间: 2012-1-1 00:26
本帖最后由 陈丹阳 于 2012-1-1 00:34 编辑
  1.     * <p>
  2.      * The {@code equals} method for class {@code Object} implements
  3.      * the most discriminating possible equivalence relation on objects;
  4.      * that is, for any non-null reference values {@code x} and
  5.      * {@code y}, this method returns {@code true} if and only
  6.      * if {@code x} and {@code y} refer to the same object
  7.      * ({@code x == y} has the value {@code true}).
  8.      * <p>
  9.      * Note that it is generally necessary to override the {@code hashCode}
  10.      * method whenever this method is overridden, so as to maintain the
  11.      * general contract for the[b] {@code hashCode} [/b]method, which states
  12.      * that equal objects must have equal hash codes.
  13.      *
  14.      * @param   obj   the reference object with which to compare.
  15.      * @return  {@code true} if this object is the same as the obj
  16.      *          argument; {@code false} otherwise.
  17.      * @see     #hashCode()
  18.      * @see     java.util.HashMap
  19.      */
  20.     public boolean equals(Object obj) {
  21.         return (this == obj);
  22.     }
复制代码
以上为Object类中的源码。从代码上可看出,子类对象.equals(父类对象) 语法上不成立,而父类对象.equals(子类对象)语法上成立。

因此若不重写该方法,实际上在子父类间意义并不大。


中文api文档的equals
public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
equals 方法在非空对象引用上实现相等关系:

自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。


参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。





作者: lvwenwen88    时间: 2012-1-4 11:20
谢谢,学习了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2