scala - Scala 中的面向对象

标签 scala

从 Martin Odersky 的 Scala 类(class)中,我有以下练习(这是给出答案的视频练习):


提供代表抽象类 Nat 的实现
非负整数

不要在此实现中使用标准数字类。
相反,实现一个子对象和一个子类。

一个用于数字零,另一个用于严格正数。


这是代码:

abstract class Nat {
  def isZero : scala.Boolean
  def predecessor : Nat
  def successor = new Succ(this)
  def + (that : Nat) : Nat
  def - (that : Nat) : Nat
}

object Zero extends Nat {
  def isZero = true
  def predecessor = throw new Error("0.predecessor")
  def + (that: Nat) = that
  def - (that: Nat) = if(that.isZero) this else throw new Error("negative number")
}

class Succ(n : Nat) extends Nat {
  def isZero = false
  def predecessor = n
  def +(that : Nat) = new Succ(n + that)
  def -(that: Nat) = n - that.predecessor
}

在 Scala 工作表中,我有:
object NatTests {
  new Successor(Zero).+(new Successor(Zero))  
}

它返回一个新的继承者。我认为我没有完全理解这段代码,因为我应该能够在不扩展代码的情况下添加非零对象?如果是这样,这是如何实现的?

最佳答案

您可以在不扩展任何类的情况下添加非零数字/对象 Nat , Zero , 或 Succ .当您使用对象时 natObj类型 Nat并构造一个新对象 new Succ(natObject)那个新对象代表一个比natObj 大一的数字。代表。

也许能够查看对象,使这更清楚一点:

abstract class Nat {
  def isZero : Boolean
  def predecessor : Nat
  def successor = new Succ(this)
  def + (that : Nat) : Nat
  def - (that : Nat) : Nat
}

object Zero extends Nat {
  def isZero = true
  def predecessor = throw new Error("0.predecessor")
  def + (that: Nat) = that
  def - (that: Nat) = if(that.isZero) this else throw new Error("negative number")

  override def toString = "0 => Zero"
}

class Succ(n : Nat) extends Nat {
  def isZero = false
  def predecessor = n
  def + (that : Nat) = new Succ(n + that)
  def - (that: Nat) = if (that.isZero) this else n - that.predecessor

  override def toString = {
    def findNumber(nat: Nat): Int = 
      if (nat.isZero) 0 
      else 1 + findNumber(nat.predecessor)
    val number = findNumber(this)
    String.valueOf(number) + " => " + 
            ((1 to number) fold ("Zero")) ( (s,_) => "Succ(" + s + ")")
  }
}

现在您的 Scala 工作表将显示一个对象代表的数字及其内部结构:
object NatTests extends App {
  val nat0 = Zero                                 
  val nat1 = new Succ(Zero)                       
  val nat2 = new Succ(nat1) // or new Succ(new Succ(Zero))
  val nat3 = new Succ(nat2) // or new Succ(new Succ(new Succ(Zero)))

  println(nat0)             //> 0 => Zero
  println(nat1)             //> 1 => Succ(Zero)
  println(nat2)             //> 2 => Succ(Succ(Zero))
  println(nat3)             //> 3 => Succ(Succ(Succ(Zero)))
  println(nat2 + nat2)      //> 4 => Succ(Succ(Succ(Succ(Zero))))
  println(nat3 + nat2)      //> 5 => Succ(Succ(Succ(Succ(Succ(Zero)))))
}

关于scala - Scala 中的面向对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16218695/

相关文章:

scala - 一种初始化Scala ArrayBuffer的惯用方式?

scala - Actor 选择

scala - 无法初始化 Scala Gradle 项目 : -bash: gradle/gradle-5. 2.1/bin/gradle:没有这样的文件或目录

python - 如何在 Windows 上安装 Polynote?

ScalaTest afterAll() 在每次测试后被调用

scala - spark 中的阶段/任务结束时是否有 "hook"?

scala - 转到 IntelliJ 中跨项目的下一个编译器错误

Scala,将多个列表转换为元组列表

scala - 将变量强制转换为 Scala 中的方法 "Runtime Evaluation"

javascript - 用于 JVM 和 JavaScript 的 headless 单源库