我有一个关于在Java中覆盖equals
方法的问题。在我的书中,我有以下例子:
public class Dog{
private String name;
private int age;
public boolean equals(Object obj) {
if(!(obj instanceof Dog)) return false;
Dog other = (Dog) obj; ---> confused here
if(this.name.equals(other.name) && (this.age == other.age) {
return true;
}
else {
return false;
}
}
}
我不明白为什么必须将引用转换为Dog
引用。如果该引用不是Dog
类型,则返回false。为什么所有的麻烦都投下它?
答案 0 :(得分:8)
声明的obj
类型为Object
,因此您必须将其强制转换为告诉编译器它是Dog
。
虽然逻辑上它在代码中的那个点上不能是任何其他内容,但编译器对逻辑一无所知 - 它只知道类型。
答案 1 :(得分:4)
因为您要为相等性定义自己的参数,所以必须确保它们是同一个类。也就是说,除非您将它们与==
方式进行比较,否则您需要比较对象内部的某些值。要比较对象内部的值,它们必须是相同的类型!
例如,假设您有两个Dog
。
Dog dog1 = new Dog("Fido");
Dog dog2 = new Dog("Rover");
如果你想测试他们是否有相同的名字,我相信你知道,你不能使用:
if(dog1 == dog2)
所以你重写了equals方法。但是,因为您要覆盖它,所以它必须具有相同的方法签名。方法签名由方法名称及其参数的数量和类型定义。这意味着如果您希望覆盖它,则需要具有Object
类型的参数。因此:
if(dog1.equals(dog2))
您需要将其强制转换为使用您用于从狗获取name
值的任何方法,并比较这些值的原因。
关于班级设计的说明
面向对象编程中的约定,当然还有Java中的约定,是使用Accessor
和Mutator
方法来获取和更改类中的变量。那就是:
dog1.name; ----> dog1.getName();
getName()
的样子:
public String getName()
{
return name;
}
答案 2 :(得分:0)
您要覆盖等于value
而不是 reference
即如果他们拥有相同 name
而age
不,如果他们归同一个人所有(即不是如果他们的参考是相同的)
如果没有演员阵容,您将无法访问狗的name
和age
成员
答案 3 :(得分:0)
对于JVM来说,obj是Dog并不是那么明显,所以你必须明确表现出演员。
答案 4 :(得分:0)
因为方法参数obj
是Object
类的实例。因此,在方法正文中,您需要将obj
转换回Dog
类型。
答案 5 :(得分:0)
属性name
和age
仅适用于Dog
。您无法使用name
age
来访问obj
或Object
。例如,以下代码将生成编译时错误:
this.name.equals(obj.name)
我不明白为什么必须将引用转换为Dog引用。如果该引用不是Dog类型,则返回false。为什么所有的麻烦都投下它?
因为虽然参考是Dog
,但这并不意味着它是同一只狗。另一只狗的名字可能与您的Dog
不一样。要将其他name
的{{1}}和age
与您的Dog
进行比较,必须先将其投射。
答案 6 :(得分:0)
我认为您的演示类缺少hashCode()方法。如果对重写的hashCode()的调用相等,则两个对象只能相等。 (相同的整数值)。
我很确定你们两个都需要保证这个等式。