1

-- Yes, this is a question asking for help regarding something that was assigned as homework. No, this is not me asking you to do my homework for me. The deadline was a half an hour ago; I literally can't change my submission. You'll just have to take my word for it. Moving on...

I know that testing for the type of objects is supposed to be unnecessary. When I was looking for details about 'instanceof', I found a half dozen threads where people responded only to tell the original poster that they were making a mistake if they had to test to find out what kind of object they were dealing with before processing it. Yes, I know, I would love to follow the conventions. Unfortunately, my professor asked for us to override the equals method of a class we defined, and specifically required an Object type parameter. If you see my code, you'll probably understand better:

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;
}

You can probably understand where I'm going with this. The 'other' parameter should be an Object type, but the program has a fit if I leave it as an Object and use the name / days / start / end fields. If I change it to Course, of course it works (no pun intended), but that would be a completely different method. The desired behavior is for all objects other than Course instances to make the method return false, and additionally, for mismatched data between Course instances to make it return false.

I'm sorry to all of you who know Java well enough to be frustrated by seeing questions like these.

Jayan
  • 18,003
  • 15
  • 89
  • 143
John P
  • 1,463
  • 3
  • 19
  • 39
  • You probably should have done a simple google search for "overriding object.equals java", and you would have had no trouble with your assignment. This is an example of a really good homework question by the way. You might want to check out a question I wrote way back when. http://stackoverflow.com/questions/185937/overriding-the-java-equals-method-quirk. Essentially, you have to cast the object to the type you think it is, and check that the conversion worked before accessing its properties. – Josh Smeaton Mar 28 '12 at 04:40
  • equals should take Object as argument. Please check http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java. It will help to understand the concept better. – Jayan Mar 28 '12 at 04:40

4 Answers4

7

If you want to override the "equals" method, you should use Object as a parameter, and thus you have to check for the object's type. Usually your own implementation would look like this:

@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));
}

Of course you should override "hashCode" as well, using the same significant fields.


Instead, you overloaded the method with your own parameter of type Course. So if you call myobject.equals(anotherObject) and anotherObject is not of type Course, your "equals" method will never be called, instead the Object#equals method will be called, which does only the following: return this == obj.


The reason why overloading the "equals" method is not enough is the necessity to overload "hashCode" as well, which takes no parameters and thus cannot be overloaded.

  • If you write your own implementation of boolean equals(Object), you must also implement int hashCode()
  • Both methods should use the same significant fields for "hashCode" and "equals".
  • If a.equals(b) == true than the following must be also true: a.hashCode() == b.hashCode()
  • Also if a.hashCode() != b.hashCode() then a.equals(b) == false

The last point is the main reason why you should not just overload "equals" with your own type:

Course c1 = new Course("myname");
Course c2 = new Course("myname");
c1.equals(c2);                   // true
c1.hashCode() == c2.hashCode();  // false
jabu.10245
  • 1,884
  • 1
  • 11
  • 20
  • 1
    The instanceof operator already returns false if the operand is null, so there is no need for the null check. – Hiro2k Mar 28 '12 at 05:06
0

You can cast Object as Course:

Course course = (Course)object;

Then do all the comparisons on the course object. Obviously, still do the instanceof check before casting to avoid a ClassCastException.

LazyCubicleMonkey
  • 1,213
  • 10
  • 17
0

You're trying to cast it:

Cource c = (Course)other;
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

Your code :

 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;
  }

Correct code :

  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;
  }