如何書寫一個恰當的equals()方法?

若有錯誤,歡迎指正。

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關鍵字進行比較了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章