类 之间的自定义相等

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 作为参数调用时的实现。

所以,我的问题是:

而不是覆盖 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 为真,前提是它们的哈希码也相同(事实并非如此)。