Consider the following classes:
public class Base {
protected int i = 0;
public Base(int i) {
this.i = i;
}
public Base(Base b) {
this(b.i);
}
public Base foo() {
return new Base(this);
}
}
public class Sub extends Base {
public Sub(int i) {
super(i);
}
public Sub(Sub s) {
super(s.i * 2);
}
public Base foo() {
return this;
}
@Override
public boolean equals(Object o) {
return ((Sub) o).i == this.i;
}
public static void main(String[] args) {
Base b1 = new Base(1);
Base b2 = b1;
Base b3 = b2.foo();
Base b4 = new Sub(1);
Base b5 = b4.foo();
System.out.println(b1.equals(b3));
}
}
The printed result is false. I've noticed the overridden method equals(Object o) never get caught and I suspect of course that this is the problem (Otherwise it would have printed true).
Why is that?

You're calling b1.equals(b3) - b1 is an instance of Base, not of Sub, so there's no way your overriding method can be called.
Heck, even b3.equals(b1) won't call anything on Sub, as b3 refers to an instance of Base as well.
Only b4 and b5 refer to instances of Sub, so only b4.equals(...) or b5.equals(...) will call your overridden method. Additionally, because you're unconditionally casting within your equals method, b4.equals(b1) (for example) will throw an exception rather than returning false.
See more on this question at Stackoverflow