Reputation:
I'm reading the book Programming in Scala (second edition) by Martin Odersky and I have a problem with the examples in Chapter 10.
This is my file almost at the end of the chapter:
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
)
}
The compiler says this:
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(
^
If I remove the class Element
from the beginning then it complains that the Element type is not found when I try to subclass it.
I found a couple topics here that are already discussing this chapter from the book but I couldn't use any of the proposed solutions there.
What did I miss?
Regards, Norbert
Upvotes: 1
Views: 4959
Reputation: 1
There is a companion object and a companion class for Element
, and I thought they could access each other's members without import
.
However, it seems that the companion can only access members protected by private
, and does not do name resolution.
So you may have to add import
beforehand in order to access the Element
object's elem
with only elem
.
Upvotes: 0
Reputation: 15074
First, you declare class Element twice - remove the first line, it is only confusing things (this doesn't cause any errors for me - if it does for you, can you show us some more info on the error?). That should fix the override errors. Second, method elem
from the companion object isn't automatically visible in the class. Either prefix it with Element
wherever it is used or - better - add an import line at the start of the class:
object Element {
...
}
abstract class Element {
import Element._
...
}
EDIT: Ah, I might have an idea why you get an error when you leave off the first line. If you are trying this in the REPL and entering it one line (or one declaration) at a time, then you might hit this issue because the REPL doesn't like the forward referencing required. Try pasting all the code in at once (using ":paste" in the REPL).
Upvotes: 6