1

I am trying to override the equals method in an abstract class. Is there a way that I can check if the parameter Object o is an instance of the class that has inherited the method and to then typecast o to same type as the class that has inherited the equals method?

This is what I have tried so far, but I am receiving the error variable of type java.lang.Object. Is there a reason that o is not being typecast? The getOperand() method returns a compound type.

@Override
public boolean equals(Object o){
    if (o.getClass() == this.getClass()){
        this.getClass().cast(o);
        return (o.getOperand().equals(this.getOperand()));
    }
    else {
        return false;
    }
}
Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
Is12Prime
  • 111
  • 6
  • "but I can't get it to work" -> why not? Is there a compile error? A runtime exception? Unexpected behaviour? Please clarify. Also, you may want to take a lookat [`Class#isAssignableFrom(...)`](https://docs.oracle.com/javase/9/docs/api/java/lang/Class.html#isAssignableFrom-java.lang.Class-) since it takes care of inheritance as well. – Turing85 Nov 05 '17 at 15:16
  • What does `getOperand()` return? I am guessting a `String`. Use `o.getOperand().equals(this.getOperand())` instead? – Chetan Kinger Nov 05 '17 at 15:18
  • "The getOperand() method returns a compound type." -> As @CKing mentioned, unless this is a singleton, you sould not compare them with `==`. In fact, [you should never compare any object with `==` unless you know exactly what you are doing](https://stackoverflow.com/questions/7520432/what-is-the-difference-between-vs-equals-in-java). – Turing85 Nov 05 '17 at 15:22
  • Possible duplicate of [What is the difference between == vs equals() in Java?](https://stackoverflow.com/questions/7520432/what-is-the-difference-between-vs-equals-in-java) – Turing85 Nov 05 '17 at 15:23

1 Answers1

2

You need to :

  1. Assign the result of the cast to your class reference type so that the compiler is able to find the getOperand method since Object class doesn't have such a method.
  2. Use the equals method to compare the operand values rather than using ==.
  3. Use instanceof so that the solution supports mixed type equality. (Read Liskov Substitution Principle. Optional if you don't want to support mixed type equality)
  4. Mark the equals method as final to prevent subclasses from overriding it inorder to support symmetry (if x.equals(y) then y.equals(x). Not required if not supporting mixed type equality)

    public abstract class EqualsTest {
        public final boolean equals(Object o) {//make equals final to maintain symmetry
            if (o instanceof EqualsTest) {//use instanceof
                EqualsTest e = (EqualsTest)o;//cast and assign to EqualTest reference
                return e.getOperand().equals(this.getOperand());//use equals here
            } else
                return false;
            }
        }
    }       
    

With the above changes, sub-classes can inherit the equals method as is :

class EqualsTestSubClass extends EqualsTest {
      //inherts the equals and getOperand methods.      
}

class EqualsTestSubClass2 extends EqualsTestSubClass {
      //inherts the equals and getOperand methods.      
}

You can then check equality of an EqualsTestSubClass instance which is a direct subclass of EqualsTest and EqualsTestSubClass2 instance which is a subclass of EqualsTestSubClass instances as follows :

EqualsTest e1 = new EqualsTestSubClass();
EqualsTest e2 = new EqualsTestSubClass2();
System.out.println(e1.equals(e2));

Note : It is a better idea to directly compare the operand field in the equals method rather than using getOperand since getOperand is overridable.

Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
  • The equals() method is in an abstract class and I can't create an instance of it the same way you declared EqualsTest e. Is there a way to generically typecast a variable to the same type as the class that will inherit the abstract method? I intend on having four classes inherit the abstract class. – Is12Prime Nov 05 '17 at 15:34
  • 1
    @JohnRolding `EqualsTest` being `abstract` wouldn't affect the answer. You are not creating an instance of `EqualTest` in the `equals` method. You are just casting the value passed to the `equals` method in `EqualTest` and assigning it to an `EqualTest` reference. – Chetan Kinger Nov 05 '17 at 15:36