The problem is that what happens if the other object ("that") belongs to a subclass of Foo, which may have its own fields? As the equals() method is only comparing the "i" field, it will ignore the other fields and return true prematurely. Below is such a subclass Bar:

With the erroneous equals() method in Foo, we could get incorrect results:

scala> val f1 = new Foo(2)f1: Foo = Foo@14c0275

scala> val b1 = new Bar(2, 3)b1: Bar = Bar@171bc3f

scala> f1.equals(b1)res0: Boolean = true

scala> b1.equals(f1)res1: Boolean = false

A solution to the problem

The problem is that the equals() method in Foo is treating the Bar object exactly as a base Foo object, but the equality contract in Bar has changed from that in Foo. Of course, not every subclass of Foo will use a different equality contract; some do and some don't (by default, we should assume that they don't). Therefore, the equals() method in Foo should make sure that the "that" object uses the same equality contract as "this":