Scala中的面向对象

时间:2013-04-25 15:21:48

标签: scala

从Martin Odersky的Scala课程中我有以下练习(这是一个给出答案的视频练习):

” 提供表示的抽象类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))  
}

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

3 个答案:

答案 0 :(得分:4)

能够添加非零数字/对象,而不会扩展任何类NatZeroSucc。当您使用类型为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)))))
}

答案 1 :(得分:0)

您最有可能希望以递归方式实施它们

我不确定确切的语法,但它就是这样的

def +(that : Nat) = (this.predecessor + that.successor)
def -(that: Nat) = if (that.isZero) this else (this.predecessor - that.predecessor) 

此外,由于您的对象是不可变的,因此没有理由每次都创建一个新对象。

答案 2 :(得分:0)

我就是这样写的:

sealed trait Nat {
  def isZero : scala.Boolean
  def predecessor : Nat
  def successor = Succ(this)
  def + (that : Nat) : Nat
  def - (that : Nat) : Nat  = 
       if (that.isZero) this else this.predecessor - that.predecessor
}

case object Zero extends Nat {
  def isZero = true
  def predecessor = sys.error("predecessor of zero")
  def + (that: Nat) = that
}

case class Succ(predecessor : Nat) extends Nat {
  def isZero = false
  def +(that : Nat) = this.predecessor + that.successor
}