类 之间的自定义相等
Custom equality between classes
我目前正在学习 Scala,过去几年编程不多,所以我可能忘记了一些 OOP 基础知识。
我正在尝试实现两个 classes:
case class Rectangle(a : Int,b : Int) extends Shape
case class Square(a : Int) extends Shape
trait/abstractclass(我都试过了,都不行)Shape
定义如下:
trait Shape {
def a : Double
def b : Double
def area = a *b
def sides = 4
def perimeter = 2 * (a+b)
def equals(r: Shape){
r.a == this.a && r.b == this.b
}
}
期望的行为是 Rectangle(2,2) == Square(2)
我认为它应该像这样工作,因为运算符 ==
应该使用 equals
方法,我希望它使用最具体的实现(使用随机调用时的默认实现 class 和我在使用另一个 Shape
作为参数调用时的实现。
所以,我的问题是:
- 如何实施?
- 是否有不应该实施的原因(例如,它与一些 OOP 原则相冲突,尽管它是可传递的、自反的和对称的)
- Shape 应该是抽象的 class 还是特征?
而不是覆盖 equals
方法,您需要在 Shape
.
中重载 ==
运算符
有关运算符重载的详细信息,请参阅下文。
https://docs.scala-lang.org/tour/operators.html
编辑:
显然,我最初的回答不够明确。请参阅下面的示例:
abstract class Shape(val a: Int, val b: Int) {
def ==(other: Shape): Boolean = this.a == other.a && this.b == other.b
}
class Square(s: Int) extends Shape(s, s)
class Rectangle(x: Int, y: Int) extends Shape(x, y)
def main (args: Array[String] ): Unit = {
println(new Square(2) == new Rectangle(2, 2)) // true
println(new Square(2) == new Rectangle(4, 2)) // false
println(new Square(2).equals(new Rectangle(4, 1))) // false
}
我发现这组幻灯片解决了问题(至少回答了我的第一个问题):https://www.slideshare.net/knoldus/object-equality-inscala (p9)
问题似乎是有必要覆盖内置的 equals 方法,而不仅仅是添加额外的重载。
override def equals(other : Any) : Boolean = other match{
case s: Shape => s.a == this.a && s.b == this.b
case _ => false
}
到目前为止,在我的测试中,这是按预期工作的。
幻灯片 13 提到 "equals" 只有 return 为真,前提是它们的哈希码也相同(事实并非如此)。
我目前正在学习 Scala,过去几年编程不多,所以我可能忘记了一些 OOP 基础知识。
我正在尝试实现两个 classes:
case class Rectangle(a : Int,b : Int) extends Shape
case class Square(a : Int) extends Shape
trait/abstractclass(我都试过了,都不行)Shape
定义如下:
trait Shape {
def a : Double
def b : Double
def area = a *b
def sides = 4
def perimeter = 2 * (a+b)
def equals(r: Shape){
r.a == this.a && r.b == this.b
}
}
期望的行为是 Rectangle(2,2) == Square(2)
我认为它应该像这样工作,因为运算符 ==
应该使用 equals
方法,我希望它使用最具体的实现(使用随机调用时的默认实现 class 和我在使用另一个 Shape
作为参数调用时的实现。
所以,我的问题是:
- 如何实施?
- 是否有不应该实施的原因(例如,它与一些 OOP 原则相冲突,尽管它是可传递的、自反的和对称的)
- Shape 应该是抽象的 class 还是特征?
而不是覆盖 equals
方法,您需要在 Shape
.
==
运算符
有关运算符重载的详细信息,请参阅下文。
https://docs.scala-lang.org/tour/operators.html
编辑:
显然,我最初的回答不够明确。请参阅下面的示例:
abstract class Shape(val a: Int, val b: Int) {
def ==(other: Shape): Boolean = this.a == other.a && this.b == other.b
}
class Square(s: Int) extends Shape(s, s)
class Rectangle(x: Int, y: Int) extends Shape(x, y)
def main (args: Array[String] ): Unit = {
println(new Square(2) == new Rectangle(2, 2)) // true
println(new Square(2) == new Rectangle(4, 2)) // false
println(new Square(2).equals(new Rectangle(4, 1))) // false
}
我发现这组幻灯片解决了问题(至少回答了我的第一个问题):https://www.slideshare.net/knoldus/object-equality-inscala (p9)
问题似乎是有必要覆盖内置的 equals 方法,而不仅仅是添加额外的重载。
override def equals(other : Any) : Boolean = other match{
case s: Shape => s.a == this.a && s.b == this.b
case _ => false
}
到目前为止,在我的测试中,这是按预期工作的。
幻灯片 13 提到 "equals" 只有 return 为真,前提是它们的哈希码也相同(事实并非如此)。