有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在采用对象参数的Java方法中,如何访问仅存在于特定类实例中的字段?

--是的,这是一个关于被分配为家庭作业的问题,请求帮助。不,这不是我让你帮我做作业。截止日期是半小时前;我真的不能改变我的意见。你得相信我的话。继续

我知道测试对象类型是不必要的。当我在寻找“instanceof”的详细信息时,我发现了六条线索,其中人们的反应只是告诉原始海报,如果他们必须在处理之前进行测试以找出他们正在处理的对象类型,那么他们是在犯错误。是的,我知道,我愿意遵守惯例。不幸的是,我的教授要求我们重写我们定义的类的equals方法,并且特别需要一个对象类型参数。如果您看到我的代码,您可能会更好地理解:

public boolean equals(Course other){
    if(!(other instanceof Course)){
        return false;
    } else if(other.name==this.name && other.days==this.days && 
        other.start==this.start && other.end==this.end){
        return true;
    }
    return false;
}

你也许能理解我的意图。“other”参数应该是对象类型,但如果我将其作为对象保留,并使用name/days/start/end字段,则程序会有一个合适的类型。如果我把它改成当然,它当然会起作用(没有双关语的意思),但那将是一个完全不同的方法。所需的行为是,除课程实例之外的所有对象使方法返回false,此外,课程实例之间的不匹配数据使其返回false

我很抱歉,对于所有熟悉Java的人来说,看到这样的问题会感到沮丧


共 (4) 个答案

  1. # 1 楼答案

    您的代码:

     public boolean equals(Course other){
         if(!(other instanceof Course)){  <-- other can only be Course here
              return false;
         } else if(other.name==this.name && other.days==this.days && 
             other.start==this.start && other.end==this.end){
             return true;
          }
         return false;
      }
    

    正确代码:

      public boolean equals(Object other){
         if(!(other instanceof Course)){
             return false;
         } else{ 
           Course c = (Course) other;
           if(c.name==this.name && c.days==this.days && 
              c.start==this.start && c.end==this.end){
             return true;
          }
         }
       } 
         return false;
      }
    
  2. # 2 楼答案

    你正试图施展它:

    Cource c = (Course)other;
    
  3. # 3 楼答案

    如果你想覆盖“equals”方法,你应该使用Object作为参数,因此你必须检查对象的类型。通常,您自己的实现如下所示:

    @Override
    public boolean equals(Object obj) {
        if (obj == this)
            return true;  // object's references are identical
        else if (!(obj instanceof Course))
            return false;
    
        Course that = (Course) obj;
        return (this.name.equals(that.name)) && (this.days == that.days)
            && (this.start.equals(that.start)) && (this.end.equals(that.end));
    }
    

    当然,您也应该重写“hashCode”,使用相同的有效字段


    相反,您使用自己的Course类型参数重载了方法。因此,如果你调用myobject.equals(anotherObject)并且anotherObject不是类型当然,你的“equals”方法将永远不会被调用,而是Object#equals方法将被调用,它只执行以下操作:^{}


    重载“equals”方法是不够的,原因是还需要重载“hashCode”,它不需要参数,因此不能重载

    • 如果你自己编写boolean equals(Object)的实现,你必须也实现int hashCode()
    • 这两种方法对“hashCode”和“equals”都应该使用相同的有效字段
    • 如果a.equals(b) == true,那么下面的也必须是真的:a.hashCode() == b.hashCode()
    • 如果a.hashCode() != b.hashCode()那么a.equals(b) == false

    最后一点是你不应该用自己的类型重载“equals”的主要原因:

    Course c1 = new Course("myname");
    Course c2 = new Course("myname");
    c1.equals(c2);                   // true
    c1.hashCode() == c2.hashCode();  // false
    
  4. # 4 楼答案

    您可以将对象强制转换为课程:

    Course course = (Course)object;
    

    然后对课程对象进行所有比较。显然,在强制转换之前仍然要进行instanceof检查,以避免出现ClassCastException