package equals;
public class EqualsTest {
    public static void main(String[] args) {
        Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
        Employee alice2 = alice1;
        Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
        Employee bob = new Employee("Bob", 50000, 1989, 10, 1);
        System.out.println("alice1==alice2:" + (alice1 == alice2));
        System.out.println("alice1==alice3:" + (alice1 == alice3));
        System.out.println("alice1.equals(alice3):" + alice1.equals(alice3));
        System.out.println("bob.toString():" + bob.toString());
        Manager carl = new Manager("Carl Cracker", 80000, 1987, 12, 15);
        Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
        boss.setBonus(5000);
        System.out.println("boss.toString():" + boss);
        System.out.println("carl.equals(boss):" + carl.equals(boss));
        System.out.println("alice1.hashCode():" + alice1.hashCode());
        System.out.println("alice3.hashCode():" + alice3.hashCode());
        System.out.println("bob.hashCode():" + bob.hashCode());
        System.out.println("carl.hashCode():" + carl.hashCode());
    }
}
package equals;
import java.time.LocalDate;
import java.util.Objects;
public class Employee {
    private String name;
    private double salary;
    private LocalDate hireDay;
    public Employee(String name, double salary, int year, int month, int day) {
        this.name = name;
        this.salary = salary;
        hireDay = LocalDate.of(year, month, day);
    }
    public String getName() {
        return name;
    }
    public double getSalary() {
        return salary;
    }
    public LocalDate getHireDay() {
        return hireDay;
    }
    public void raiseSalry(double byPercent) {
        double raise = salary * byPercent / 100;
        salary += raise;
    }
    public boolean equals(Object otherObject) {
        // a quick test to see if the objects are identical
        if (this == otherObject) return true;
        //must return false if the explict parameter is null
        if (otherObject == null) return false;
        //if the classes don't match, they can't be equal
        if (getClass() != otherObject.getClass()) return false;
        //now we know otherObject is a non-null Employee
        Employee other = (Employee) otherObject;
        //test whether the fields have identical values
        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 getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
    }
}
package equals;
public class Manager extends Employee {
    private double bouns;
    public Manager(String name, double salary, int year, int month, int day) {
        super(name, salary, year, month, day);
        bouns = 0;
    }
    @Override
    public double getSalary() {
        double baseSalary = super.getSalary();
        return baseSalary + bouns;
    }
    @Override
    public void raiseSalry(double byPercent) {
        super.raiseSalry(byPercent);
    }
    public void setBonus(double bouns) {
        this.bouns = bouns;
    }
    public boolean equals(Object otherObject) {
        if (!super.equals(otherObject)) return false;
        Manager other = (Manager) otherObject;
        // super.equals checked that this and other belong to the same class
        return bouns == other.bouns;
    }
    public int hashCode() {
        return java.util.Objects.hash(super.hashCode(), bouns);
    }
    @Override
    public String toString() {
        return super.toString() + "[bouns=" + bouns + "]";
    }
}