这个问题在这里已经有答案了:
重写java equals()方法-不工作(8个答案)
19天前关门了。
我有一个学生班,扩展了一个人班。我的超类中没有equals方法,只有图中所示的子类中的两个方法。我试图理解我的第二、第三和第四个print语句的运行时行为。语句1调用接受student参数的equals方法,这很有意义,因为两个被比较的对象都声明为student类型。但是,语句2调用equals方法,该方法接受person参数,而最后两个语句调用object类中的equals方法。有人能解释为什么java是动态类型的,而实际的运行时对象总是一个学生。提前为任何错误道歉!我是新来的,对java也是新来的。我不太关心每个方法的输出,只关心调用哪个方法以及调用原因。
public boolean equals(Student s) {
System.out.println("inside student equals");
return true;
}
public boolean equals(Person p) {
System.out.println("inside person equals");
return false;
}
public static void main(String[] args) {
Student s1 = new Student("John", "1", 10, 1.0, 10);
Student s2 = new Student("John", "1", 10, 1.0, 10);
Person s3 = new Student("John", "1", 10, 1.0, 10);
Person s4 = new Student("John", "1", 10, 1.0, 10);
System.out.println(s1.equals(s2)); // 1
System.out.println(s1.equals(s3)); // 2
System.out.println(s3.equals(s4)); // 3
System.out.println(s3.equals(s1)); // 4
}
输出:
inside student equals
true
inside person equals
false
false
false
3条答案
按热度按时间2guxujil1#
其中person object是调用student的重载equals的参数。这就是为什么你得到打印声明。如果你想把它作为一个学生来比较,那么你需要输入cast。
在对person对象调用equals的情况下,它最终返回一个false,因为person类中没有实现equals。。。然后它默认为对象的实现,即“检查null,然后检查引用是否相同…”。。。否则返回false”。您可以在jdk的源代码中查看实现。
0ejtzxu12#
你犯的最大的错误就是,失踪
@Override
带有equals
方法。一旦你要做这件事。和
一旦您这样做,您的ide将无法编译,迫使您更正应该修改的定义
Object
而不是Person
或者Student
类型作为参数。关于您获得的输出:
在这四个调用中,都没有覆盖
Object#equals
将被调用。毫无疑问
Student#equals
将在第一次调用中调用,因为两个引用都是Student
类型。在剩下的三次通话中,Person#equals
将被调用,因为最接近的匹配。您可以查看此演示以获取说明。
更新
如果你把
equals
内部方法Student
如这里所示,您应该更容易理解输出。如果你愿意的话
Student#equals
要在最后两个案例中也被调用,您将需要s3
至Student
如下图所示:plupiseo3#
根据声明的类型,在编译时确定使用哪个重载方法。
在第二种情况下,您已经声明s3是一个人,因此
equals(Person)
方法。在第3和第4种情况下,您已经将变量声明为person。person没有equals()方法,因此编译器假定您要使用object中的默认方法:
您尚未在任何类中重写该方法,因此默认方法是在运行时使用的方法。