I'm reading through Programming in Scala. It says:
You can redefine the behavior of
==for new types by overriding theequalsmethod, which is always inherited from classAny. The inheritedequals, which takes effect unless overridden, is object identity, as is the case in Java. Soequals(and with it,==) is by default the same aseq, but you can change its behavior by overriding theequalsmethod in the classes you define. It is not possible to override==directly, as it is defined as a final method in classAny. That is, Scala treats==as if was defined as follows in classAny:final def == (that: Any): Boolean = if (null eq this) (null eq that) else (this equals that)
But this isn't jibing with what I'm seeing in scala 2.9.1, where it seems like:
== doesn't seem to default to equals
== directly (without complaint from the compiler, no override needed).So it seems to me like either:
I'm doing it wrong - this definition of Rational gives
% scala
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).
Type in expressions to have them evaluated.
Type :help for more information.
scala> Rational(1) == Rational(1)
res0: Boolean = false
scala> Rational(1) equals Rational(1)
res1: Boolean = true
or I'm reading an out of date version of the book, and things have changed.
What's going on?
But in Scala, == is testing for value equality. Let's understand with example. Example : Scala.
== is a final method, and calls . equals , which is not final. This is radically different than Java, where == is an operator rather than a method and strictly compares reference equality for objects.
equals() is a method defined in the Object class thus the default implementation of the . equals() method compares the object references or the memory location where the objects are stored in the heap. Thus by default the . equals() method checks the object by using the “==” operator.
You are making a very understandable mistake--you are trying to write a type-safe equals (i.e. def equals(r: Rational)) instead of a generic equals (i.e. override def equals(a: Any)).
So instead of overriding equals--note that you don't need the override keyword!--you are creating another method by overloading the type parameters, and then having two equals methods, one which takes Rational and one which takes Any. Same thing with ==; only the Any-parameterized method cannot be overridden.
To get the behavior consistent with Java (and the Scala library), you'd need to rewrite equals as something like
override def equals(a: Any) = a match {
case r: Rational => numer == r.numer && denom == r.demon
case _ => false
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With