【问题标题】:Scala companion object with abstract class具有抽象类的 Scala 伴随对象
【发布时间】:2013-08-19 21:10:56
【问题描述】:

我正在阅读 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 类型。

我在这里找到了几个主题,这些主题已经在讨论书中的这一章,但我无法使用那里提出的任何解决方案。

我错过了什么?

问候, 诺伯特

【问题讨论】:

    标签: scala


    【解决方案1】:

    首先,您两次声明类 Element - 删除第一行,这只会使事情变得混乱(这对我来说不会导致任何错误 - 如果对您有影响,您能否向我们展示更多有关该错误的信息?) .那应该修复覆盖错误。其次,伴随对象中的方法elem 在类中不会自动可见。无论在哪里使用,都可以在其前面加上 Element,或者 - 更好的是 - 在类的开头添加一个导入行:

    object Element {
      ...
    }
    
    abstract class Element {
      import Element._
      ...
    }
    

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

    【讨论】:

    • 谢谢,问题是我把导入放错了地方。书中说我必须把它放在课外。现在可以了。 ;)
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多