我正在阅读Scala编程。它说:
您可以通过覆盖
==
方法重新定义equals
对新类型的行为,该方法始终从类Any
继承。除非被覆盖,否则继承的equals
是对象标识,就像Java中的情况一样。因此,equals
(以及==
)默认情况下与eq
相同,但您可以通过覆盖您定义的类中的equals
方法来更改其行为。无法直接覆盖==
,因为它被定义为类Any
中的最终方法。也就是说,Scala将==
视为在课程Any
中定义如下:final def == (that: Any): Boolean = if (null eq this) (null eq that) else (this equals that)
但这并不是我在scala 2.9.1中看到的内容,它看起来像是:
==
似乎默认为equals
==
(无需编译器投诉,不需要override
)。所以在我看来也是如此:
我做错了 - this definition of Rational
给出了
% 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
或者我正在读这本书的过时版本,事情已经发生了变化。
发生了什么事?
答案 0 :(得分:21)
你犯了一个非常容易理解的错误 - 你试图写一个类型安全的等号(即def equals(r: Rational)
)而不是通用的等号(即override def equals(a: Any)
)。
所以不要覆盖equals
- 请注意,您不需要override
关键字! - 您正在通过重载类型参数创建另一个方法,然后使用两个< / em>等于方法,一个取Rational
,另一个取Any
。与==
相同;只有Any
- 参数化方法无法覆盖。
要使行为与Java(和Scala库)保持一致,您需要将equals重写为类似
的内容override def equals(a: Any) = a match {
case r: Rational => numer == r.numer && denom == r.demon
case _ => false
}