複写Objectスーパークラスのequals,hashCode,toStringメソッド

8054 ワード

ObjectクラスはJava内のすべてのクラスの始祖であり、Javaでは各クラスが彼によって発展したことを知っていますが、このように書く必要はありません.
class Employee extends Object   

クラスのスーパークラスを正確に指摘しなければ,Objectはこのクラスのスーパークラスとみなされるからである.継承されたルールに従って、Objectタイプの変数を使用してクラスのオブジェクトを参照できます.
Object obj = new Student (“lily”,17);
もちろん、Objectタイプの変数は、様々な値の汎用実行者としてのみ使用できます.その内容を具体的に操作するには、オブジェクトの元のタイプを明確にし、復元する必要があります.
Student stu = (Student) obj ;
Objectクラスは、equals,hashCode,toStringメソッドの3つの一般的なメソッドを提供していますが、スーパークラスが提供するメソッドは、サブクラスの要件を満たすことができず、メソッドの再書き込みが必要になる可能性があります.
(1)equalsメソッド
Objectクラスのequalsメソッドは、あるオブジェクトが別のオブジェクトに等しいかどうかを検出するために使用されます.Objectクラスでは、このメソッドは、2つのオブジェクトが同じ参照であるかどうかを判断します.2つのオブジェクトが同じ参照を持っている場合は、等しいと判断します.この点から見ると,この点はObjectクラスの操作にも合理的であるが,彼を継承する大きな対数クラスには適用されない可能性がある.たとえば、2つのStudioオブジェクトの場合、名前が一致すると学号が等しいとみなされます.
class Employee
{
   .... 
   public boolean equals(Object otherObject)
	{
		//        
		if (this == otherObject)
			return true;
		
		//    null    
		if(otherObject == null)
			return false;
		
		//                 
		if(this.getClass() != otherObject.getClass())//getclass              
			return false;
		
		Employee other = (Employee) otherObject;
		//            
		return Objects.equals(name, other.name) && salary == other.salary &&
				Objects.equals(hireDay, other.hireDay);
	}
} 
サブクラスでequalsメソッドを定義する場合、まずスーパークラスのequalsメソッドを呼び出し、検出に失敗するとオブジェクトが等しくなることは不可能であり、スーパークラスのドメインが等しい場合、サブクラスに新たに追加されたドメインに基づいて検出する.
public class Manager extends Employee {
    ......
     public boolean equals(Object otherObject)
	{
		//super.equals     otherObject  bonus        
		if (!super.equals(otherObject))
			return false;
		
		Manager manager = (Manager) otherObject;
		return bonus ==manager.bonus;
	}
}
Javaにおけるequalsメソッドの要件は次のとおりです.
   1、自己反転性:空でない参照xの場合、x.equals(x)はtrueを返します.
    2、対称性:任意の参照xおよびyに対して、y.equals(x)がtrueを返す場合にのみ、x.equals(y)もtrueを返す.
   3、伝達性:任意の参照x,y,zに対して、x.equals(y)がtureに戻り、y.equals(z)がtrueに戻る場合、x.equals(z)もtrueに戻るべきである.
   4、一致性:x,yが何も変化していない場合、x.equals(y)を繰り返し呼び出すと、同じ結果が返されます.
   5、任意の非空参照xに対して、x.equals(null)はfalseを返すべきである.
ps:Javaで  ==  の要求は、等号の左右の両側が同じ引用対象であることを真とする.ドメインは等しく、同じ参照ではなく偽です.
比較的完璧なequalsメソッドを作成するには、次の手順に従います.
1、表示パラメータの名前は:otherObjectで、後で他のotherという変数に変換します.
2.thisとotherObjectが同一参照であるかどうかを検査する:
if  (this == otherObject)  return true; 

3、otherObjectがnullであるかどうかを検出し、nullであればfalseを返し、
if(otherObject == null)  return false;

4、thisとotherObjectが同じクラスかどうかを比較し、getClassメソッドで検出することができる.
if(this.getClass() != otherObject.getClass())
	return false;
すべてのサブクラスに共通の意味がある場合はinstanceof検出を使用します.
if(!(otherObject instanceof ClassName))   return false

5.otherObjectを対応するクラス型変数に変換する
Employee other = (Employee) otherObject;

6、比較が必要なドメインを比較する.==を使用して基本タイプの比較を行い、equalsを使用してオブジェクトドメインの比較を行います.すべてのドメインが一致する場合はtrueを返し、そうでない場合はfalseを返します.
return Objects.equals(name, other.name) && salary == other.salary &&Objects.equals(hireDay, other.hireDay);

(2)hashCodeメソッド
ハッシュコード(hash code)は、オブジェクトから導出される整数値である.ハッシュコードは規則的ではありません.x,yが2つの異なるオブジェクトである場合、一般的にx.hashCode()とy.hashCode()の値は異なる.hashCodeはObjectクラスに定義されているため、各オブジェクトにはデフォルトのハッシュコードがあり、その値はオブジェクトの格納アドレスです.
equalsメソッドを再定義した場合、hashCodeメソッドを再定義して、ユーザーがハッシュ・リストにオブジェクトを挿入できるようにする必要があります.
hashCodeメソッドは、整数値(負の値である可能性がある)を返し、インスタンスドメインのハッシュコードを合理的に組織して、各異なるオブジェクトで生成されるハッシュコードをより均一にすることができるようにしなければならない.
public int hashCode()
	{
            //          ,    Objects.hash       
           return Objects.hash(name, salary, hireDay);
	}
equalsはhashCodeの定義と一致し、x.equals(y)がtrueの場合、x.hashCode()の値はy.hashCode()の値と等しくなければならない.
(3)toString方法
    Objectクラスに付属するtostringメソッドは、サブクラスの要件を満たすことができない可能性があるため、通常、サブクラスでクラスのtoStringメソッドを再定義する必要があります.
 TOstringメソッドが随所に見られる主な理由の1つは、オブジェクトと文字列がオペレータ「+」で操作されると、JavaがオブジェクトのtoStringメソッドを自動的に呼び出すためです.
xがオブジェクトの場合、System.out.println(x)が実行されると、xは自動的にx.toString()に変換され、得られた文字列が印刷されます.
public String toString()
	{
		return "name"+ name+ "salary"+ salary+ "hireDay"+ hireDay;
	}

以下のプログラムはEmployeeクラスとManagerクラスのequals、hashode、toString方法を実現した.
package equals_hashCode_toString;


import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Objects;

import commonly_class.string;

public class Employee {

	private String name;
	private double salary;
	private Date hireDay;
	
	public Employee(String name, double salary,int year, int month, int day)
	{
		this.name = name;
		this.salary = salary;
		GregorianCalendar gregorianCalendar = new GregorianCalendar(year, month-1, day);
		hireDay = gregorianCalendar.getTime();
	}

	public String getName()
	{
		return name;
	}

	public double getSalary() 
	{
		return salary;
	}

	public Date getHireDay() 
	{
		return hireDay;
	}
	
	public void raiseSalary(double byPrecent)
	{
		double raise = salary * byPrecent /100;
		salary = salary + raise;
	}
	
	public boolean equals(Object otherObject)
	{
		//        
		if (this == otherObject)
			return true;
		
		//    null    
		if(otherObject == null)
			return false;
		
		//                 
		if(this.getClass() != otherObject.getClass())
			return false;
		
		Employee other = (Employee) otherObject;
		//            
		return Objects.equals(name, other.name) && salary == other.salary &&
				Objects.equals(hireDay, other.hireDay);
	}
	
	public int hashCode()
	{
		return Objects.hash(name, salary, hireDay);
	}
	
	public String toString()
	{
		return "name"+ name+ "salary"+ salary+ "hireDay"+ hireDay;
	}
}
package equals_hashCode_toString;

public class Manager extends Employee {
	private double bonus;
	
	public Manager(String name, double salary, int year, int month, int day) {
	     super(name, salary, year, month, day);
	     bonus = 0;
	}
	
	public double getSalary()
	{
		double baseSalary = super.getSalary();
		return baseSalary + bonus;
	}
	
	public void setBonus (double bonus)
	{
		this.bonus = bonus;
	}
	
	public boolean equals(Object otherObject)
	{
		//super.equals     otherObject  bonus        
		if (!super.equals(otherObject))
			return false;
		
		Manager manager = (Manager) otherObject;
		return bonus ==manager.bonus;
	}
	
	public int hashCode() {
		return super.hashCode()+ 17* new Double(bonus).hashCode();
	}
	
	public String  toString() {
		return super.toString()+"bonus"+ bonus;
	}
}
package equals_hashCode_toString;

public class EqualsTest {

	public static void main(String[] args) {
		Employee Alice1 = new Employee("Alice", 7500, 2016, 10, 17);
		Employee Alice2 = Alice1;
		Employee Alice3 = new Employee("Alice", 7500, 2016, 10, 17);
		Employee Bob = new Employee("Bob", 7500, 2016, 10, 17);
		
		System.out.println("Alice1 == Alice2:" +(Alice1 == Alice2));
		System.out.println("Alice1 == Alice3:" +(Alice1 == Alice3));
		System.out.println("Alice1.equals(Alice2):" +(Alice1.equals(Alice2)));
		System.out.println("Alice1.equals(Alice3):" +(Alice1.equals(Alice3)));
		
		System.out.println("Alice1.hashCode():"+Alice1.hashCode());
		System.out.println("Alice2.hashCode():"+Alice2.hashCode());
		System.out.println("Alice3.hashCode():"+Alice3.hashCode());
		
		System.out.println("Bob.toString: "+ Bob.toString());
		
		Manager Lily1 = new Manager("Lily", 4000, 2015, 3, 77);
		Manager Lily2 = new Manager("Lily", 4000, 2015, 3, 77);
		Lily1.setBonus(3500);
		System.out.println("Lily1.toString:"+Lily1.toString());
		System.out.println("Lily1.equals(Lily2):"+ Lily1.equals(Lily2));
		
		System.out.println("Lily1.hashCode():"+Lily1.hashCode());
		System.out.println("Lily2.hashCode():"+Lily2.hashCode());
		
	}

}