若有錯誤,歡迎指正。
Object類中的equals()方法默認比較的是對象之間的引用是否一樣,但在實際開發中需要比較的是對象之間的狀態是否一樣。這就要求我們覆寫equals()方法。
考慮繼承層次下的equals()方法應如何書寫?
1、父類的equals()方法比較共有屬性部分,等待子類中的equals()調用
2、子類各自覆寫equals()方法比較新增屬性部分
下面以Person, Student, Teahcer這三個類舉例
Person類
package com.test.equals;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
// 採用getClass()方法來比較雙方是否屬於同一個類
if (this.getClass() != obj.getClass()) {
System.out.println("The this's class name is " + this.getClass());
System.out.println("The obj's class name is " + obj.getClass());
return false;
}
Person person = (Person) obj;
return this.name.equals(person.name) && (this.age == person.age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Student類
package com.test.equals;
public class Student extends Person {
private int score;
public Student(String name, int age, int score) {
super(name, age);
this.score = score;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {
// 通過父類的equals方法,已經確定比較雙方同屬於一個類,父類中的公有屬性值也一樣
Student student = (Student) obj;
// 開始比較子類中特有的屬性值是否一樣
return this.score == student.score;
}
return false;
}
}
Teacher類
package com.wujilin.equals;
public class Teacher extends Person {
private int salary;
public Teacher(String name, int age, int salary) {
super(name, age);
this.salary = salary;
}
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {
// 通過父類的equals方法,已經確定比較雙方同屬於一個類,父類中的公有屬性值也一樣
Teacher teacher = (Teacher) obj;
// 開始比較子類中特有的屬性值是否一樣
return this.salary == teacher.salary;
}
return false;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
}
注意:
1、super關鍵字,並不是指父類對象的引用,它只是告訴編譯器要去調用父類的方法的關鍵字。
2、考慮到繼承,所以採用getClass()進行檢測,而不是使用instanceof關鍵字來比較,這是因爲子類有自己的相等概念。
舉個例子,如果使用的是instanceof關鍵字,父類中的equals()方法應該爲:
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof Person) {
// obj是Person類對象或Student類對象或Teahcer類對象的引用,都會進入到該if語句塊裏
Person person = (Person) obj;
return this.name.equals(person.name) && (this.age == person.age);
}
return false;
}
當Student子類對象和Teacher子類對象的名字和年齡都一樣的情況下,那麼要如何在子類中所覆寫的equals()方法再進一步比較這兩個對象呢?
所以,如果是由超類來決定相等的概念的話,那麼就可以使用instanceof關鍵字進行比較了。