Scala伴侣对象与抽象类

时间:2013-08-19 21:10:57

标签: scala

我正在阅读Martin Odersky的“Scala编程”(第二版)一书,我对第10章中的例子有疑问。

这几乎是本章末尾的文件:

class Element
object Element {

  private class ArrayElement(
    val contents: Array[String]
  ) extends Element

  private class LineElement(s: String) extends ArrayElement(Array(s)) {
    override def width = s.length
    override def height = 1
  }

  private class UniformElement(
    ch: Char,
    override val width: Int,
    override val height: Int
  ) extends Element {
    private val line = ch.toString * width
    def contents = Array.fill(height)(line)
  }

  def elem(contents: Array[String]): Element =
    new ArrayElement(contents)

  def elem(chr: Char, width: Int, height: Int): Element =
    new UniformElement(chr, width, height)

  def elem(line: String): Element = 
    new LineElement(line)

}

abstract class Element {
  def contents: Array[String]

  def width: Int = 
    if (height == 0) 0 else contents(0).length

  def height: Int = contents.length

  def above(that: Element): Element =
    elem(this.contents ++ that.contents)

  def beside(that: Element): Element =
    elem(
      for (
        (line1, line2) <- this.contents zip that.contents
      ) yield line1 + line2
    )
}

编译器说:

defined class Element
<console>:15: error: method width overrides nothing
           override def width = s.length
                        ^
<console>:16: error: method height overrides nothing
           override def height = 1
                        ^
<console>:21: error: value width overrides nothing
           override val width: Int,
                        ^
<console>:22: error: value height overrides nothing
           override val height: Int
                        ^
<console>:17: error: not found: value elem
           elem(this.contents ++ that.contents)
           ^
<console>:20: error: not found: value elem
           elem(
           ^

如果我从头开始删除class Element,那么当我尝试将其子类化时,它会抱怨找不到Element类型。

我在这里发现了一些已经在讨论本章的主题,但我无法使用任何提议的解决方案。

我错过了什么?

此致 诺贝特

2 个答案:

答案 0 :(得分:4)

首先,你声明类Element两次 - 删除第一行,它只会让人感到困惑(这不会给我带来任何错误 - 如果它对你有用,你能告诉我们一些关于错误的更多信息吗?) 。这应该可以解决覆盖错误。其次,来自伴随对象的方法elem在类中不会自动显示。无论在哪里使用Element都加上前缀,或者 - 更好 - 在课程开头添加导入行:

object Element {
  ...
}

abstract class Element {
  import Element._
  ...
}
编辑:啊,我可能知道你离开第一行时为什么会出错。如果您在REPL中尝试此操作并一次输入一行(或一个声明),那么您可能会遇到此问题,因为REPL不喜欢所需的前向引用。尝试一次粘贴所有代码(在REPL中使用“:paste”)。

答案 1 :(得分:0)

Element 有一个伴生对象和一个伴生类,我认为它们可以在没有 import 的情况下访问彼此的成员。 但是,同伴似乎只能访问受private保护的成员,而不会进行名称解析。 因此,您可能必须事先添加 import 才能仅使用 Element 访问 elem 对象的 elem