时间:2018-01-29 14:03:44

标签: scala oop equality

我目前正在学习Scala,并且在过去的几年里没有编程,所以我可能忘记了一些OOP基础知识。

我正在尝试实现这两个类:

case class Rectangle(a : Int,b : Int) extends Shape
case class Square(a : Int) extends Shape

特质/抽象类(我试过两种,都不起作用)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方法(当使用一些随机类调用时的默认实现以及调用时我的实现用另一个Shape作为参数。

所以,我的问题是:

  • 如何实施?
  • 是否有理由不应该实施(例如,它与某些OOP原则相冲突,尽管它具有传递性,反身性和对称性)。
  • Shape应该是抽象类还是特质?

2 个答案:

答案 0 :(得分:1)

我发现这组幻灯片解决了这个问题(至少回答了我的第一个问题):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中,它提到"等于"如果它们的哈希码也是相同的(情况并非如此),则只应返回true。

答案 1 :(得分:0)

您需要在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
  }