Reputation: 1581
-- 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.
Upvotes: 1
Views: 15935
Reputation: 1892
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.
boolean equals(Object)
, you must also implement int hashCode()
a.equals(b) == true
than the following must be also true: a.hashCode() == b.hashCode()
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
Upvotes: 7
Reputation: 848
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;
}
Upvotes: 0
Reputation: 1243
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.
Upvotes: 0