Reputation: 23
@Override
public boolean equals(Object obj){
if(obj == this){
return true;
}
if(obj instanceof Circle){
Circle circle = (Circle) obj;
if(circle.getWidth()==getWidth())
return true;
}
Says I must return a boolean, but I am, I am telling the compiler to return true; ??
Upvotes: 0
Views: 120
Reputation: 1155
All paths must return. You can't define a method that "not always" returns the value you said it would. (at least not in a strongly typed language, as Java is). The thing is, you say if that given object is a circle, and if it has the same width as this object (the instance), then it is the same object. But you never tell the compiler what if the object isn't a circle? Or what of it is one, but doesn't have the same width?
The correct way to fix that is to add an else clause to your if statement, turning it into an extended if statement. Let's take a look:
@Override
public boolean equals( Object obj )
{
if( obj == this )
{
return true;
}
else if( obj instanceof Circle )
{
Circle circle = ( Circle ) obj;
if( circle.getWidth( ) == getWidth( ) )
return true;
}
return false; //this is what's missing, now the compiler knows what to do
}
}
anymore doubts like that and you can personally message me. People will downvote you to oblivion here, if you keep asking such questions. Send them directly to me and I'll either provide you with the answer (if I'm awake and know the answer), or I'll risk my own reputation for your sake, in case I don't know the answer, since I got a tiny bit to spare.
Carlos, Could you give me a break? no idea how 4 spaces got in there. I don't want to attract sympathy or any other feeling, I just actually want to help people, not show off. I'm wrong very often, and this is why I identify with people who are wrong too. Not only obscurely wrong, but wrong on basic stuff. People deserve respect and actual answers, no matter what their question is. My personal and humble opinion only, I hope it doesn't disturb the website in anyway?
Upvotes: -1
Reputation: 1507
Please read the Java API specifications carefully. It clearly reads:
It is symmetric: for any non-null reference values x and y,
x.equals(y)
should return true if and only ify.equals(x)
returns true.
So unfortunately any implementation for a non-final class that is based on an obj instanceof MyClass
-style condition does eventually violate that rule.
Imagine that you extend Circle
by FilledCircle
which has a new field backgroundColor
and instantiate one Circle x
with width = 1 and one FilledCircle y
with width = 1 and backgroundColour = red. When implementing equals
like suggested in the other answers x.equals(y)
will yield true
because y
is an instance of Circle
and the widths are identical. But y.equals(x)
will yield false
because x
is not an instance of FilledCircle
.
A correct implementation would look like this (generated by Eclipse and quite verbose but it looks like this if you don't want to violate the contract for the equals
-method:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Circle other = (Circle) obj;
if (width != other.width)
return false;
return true;
}
Upvotes: 1
Reputation: 65540
You aren't returning something along all paths of the function.
If obj
isn't this and it's not an instance of Circle, then this function doesn't return anything.
The function you probably want looks something like this:
@Override
public boolean equals(Object obj){
if(obj == this){
return true;
}
if(obj instanceof Circle){
Circle circle = (Circle) obj;
if(circle.getWidth()==getWidth())
return true;
}
return false;
}
Upvotes: 3