I'm reading through Programming in Scala. It says:
You can redefine the behavior of
==
for new types by overriding theequals
method, 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 theequals
method 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