问题
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 toequals
- I can override
==
directly (without complaint from the compiler, nooverride
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?
回答1:
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
}
来源:https://stackoverflow.com/questions/9853645/scala-does-default-to-equals