例如,我有以下代码。
class Circle {
double radius;
public boolean equals(Object circle) {
return this.radius ==((Circle)circle).radius;
}
}
还有司机
public class Driver {
public static void main(String[] args) {
Object circle1 = new Circle();
Circle circle2 = new Circle();
System.out.println(circle1.equals(circle2));
}
}
它显示True,但是如果我将Circle.equals()重写为
public boolean equals(Circle circle) {
return this.radius ==((Circle)circle).radius;
}
其中.equals()方法采用Circle类型,系统将输出False。
我知道Circle类是Object类的子类,因此编译器不会报告错误,并且在运行时,JVM选择正确的重写方法来实现正确的行为。
如果我将代码修改为最低代码,.equals()接受Circle类对象,则代码可以正确实现,请告诉我原因。预先感谢。
答案 0 :(得分:3)
带有方法签名
public boolean equals(Circle circle) {
您正在超载 equals
,而不是覆盖它;这不是编译器错误。这意味着Circle
将继承Object
的{{1}}实现,该实现只是比较对象引用以查看它们是否相等。这将返回equals
。
您的false
方法应使用equals
才能正确覆盖该方法。您还应该使用Object
注释,如果带注释的方法未覆盖超类中的方法,则它将产生编译器错误。 method主体应在强制转换之前测试其参数是否为该类的实例,以便它可以返回@Override
而不是抛出false
。
此外,如果您要覆盖ClassCastException
,那么最好覆盖hashCode
。
答案 1 :(得分:2)
在Java中,返回类型是协变的,这意味着您可以将子类用作重写方法的返回类型。
例如,这是有效的:
public class Foo{
@Override
public Foo clone(){
...
}
}
但是参数类型不是协变的。因此,您可以在第二个代码中重载该方法,而不用覆盖它。
用@Override
注释该方法,它将不再编译:
@Override
public boolean equals(Circle circle) {
return this.radius ==((Circle)circle).radius;
}