0

There is an Employee class and a class called Manager that extends Employee. The two have same fields, but Manager has one extra field called bonus. The equals method for Manager is:

public boolean equals(Object otherObject){
    if(!super.equals(otherObject) 
        return false; 
    Manager other = (Manager) otherObjetc;
    return this.bonus == other.bonus;
}

We create employeeObj and managerObj as an instance of Employee and Manager class respectively, such that all their fields are identical (except the bonus which employeeObj doesn't have at all).

Then if we call the managerObj.equals(employeeObj) does the if condition return false? if the answer is 'no', then do we get any error for the cast or the line after it because employee doesn't have a bonus field?

The book that this example is from claims that super.equals checks if this and otherObjetc belong to the same class. But I think they didn't take into account that the method will throw exception if we pass to it an instance of employee class. Correct me if i am wrong...

Here is the equals method for employee class:

public boolean equals (Object otherObjetc){
    if (this==otherObjetc) 
        return true;
    if (otherObject == null) 
        return false;
    if (getClass() != otherObject.getClass()) 
        return false;
    Employee other = (Employee) otherObject;
    return name.equals(other.name) && salary==other.salary
}
nasukkin
  • 2,460
  • 1
  • 12
  • 19
  • `employeeObj.equals(managerObj)` may return true, but `managerObj.equals(employeeObj)` will always return false – Guillaume F. Aug 24 '17 at 19:13
  • https://stackoverflow.com/questions/13162188/java-equals-method-in-base-class-and-in-subclasses – shmosel Aug 24 '17 at 19:13
  • By the definition of equals, `a.equals(b)` and `b.equals(a)` must return the same result. So if Manager extends Employee, then a Manager can be used in place of an Employee without error thanks to polymorphism. The above code, while it will compile and run, is invalid because it violates the contract of the equals method. – Tezra Aug 24 '17 at 19:27
  • Show the `super` implementation please. – shmosel Aug 24 '17 at 19:28
  • @Tezra If OP tries to sort a mixed list of Employee and Manager objects (and the list is big enough), "Timsort" could very likely throw a "Contract Violation" exception due to the `a.equals(b)` but `b.notEquals(a)` issue coded into the equals method above. (Because compareTo() and hashCode() are written to return consistent results with equals() right?) – geneSummons Aug 24 '17 at 19:50

2 Answers2

1

Then if we call the managerObj.equals(employeeObj) does the if condition return false?

Yes, it shall return false.

if the answer is 'no', then do we get any error for the cast or the line after it because employee doesn't have a bonus field?

No, you wouldn't get a ClassCastException, since

if(!super.equals(otherObject)) return false; 

completes the execution and returns anyway and you do not reach

Manager other = (Manager) otherObject;

which can possibly throw a class cast exception.

Test code with some sample fields defined in the Employee and Manager models:

Employee employee = new Employee();
employee.setName("null");
employee.setSurname("pointer");
Manager manager = new Manager();
manager.setName("null");
manager.setSurname("pointer");
manager.setBonus(10);
System.out.println(manager.equals(employee));

Edit: The reason why

!super.equals(otherObject) 

evaluates to true and ultimately return false is because within equals of its super class

if (getClass() != otherObject.getClass()) return false;

getClass() (evaluates to Manager) and otherObject.getClass() (evaluates to Employee) are both difference classes.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • Why would if(!super.equals(otherObject) return false? The two objects have identical fields except that bonus is not defined for employee class. Doesn't this line check the equally of all fields except bonus? Then it should return TRUE. right? –  Aug 24 '17 at 19:26
  • `super.equals(otherObject)` will return true if it uses `instanceof`. – shmosel Aug 24 '17 at 19:26
  • 1
    It doesn't. i will edit the question to include the equals method for the employee as well. –  Aug 24 '17 at 19:29
  • @MehrdadFarsadyar That would depend on the implementation of equals in the super class(Employee) in your case. Also as pointed by shmosel, if it uses instanceof internally, it might return True as well. My bad, I just shared one assuming an example of what I was trying to create. – Naman Aug 24 '17 at 19:29
  • @shmosel Agreed. Would now await the edit by OP to get things clear. – Naman Aug 24 '17 at 19:30
  • @MehrdadFarsadyar Updated the answer with the updated equals for Employee class. – Naman Aug 24 '17 at 19:40
  • 1
    @nullpointer thank you for your answer. My mistake was that I thought the getClass() returns the class for the super class (so Employee) and not the class for managerObjetc. –  Aug 24 '17 at 19:57
  • @MehrdadFarsadyar welcome. I hope it helps. Not sure why is the answer still downvoted thouhgh :) – Naman Aug 24 '17 at 20:00
  • 1
    I downvoted originally because it was unsubstantiated. Upvoted now. – shmosel Aug 24 '17 at 20:37
0

If you cast an object that is not a Manager to Manager, you will get an exception.

This is why Java is type-safe.

Naman
  • 27,789
  • 26
  • 218
  • 353
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • that is what i thought too, but this is an example from a book and maybe I am wrong but it seems to me they didn't take this into account! –  Aug 24 '17 at 19:11
  • @MehrdadFarsadyar: If they're different types, `super.equals()` will return false. – SLaks Aug 24 '17 at 19:29