8

I have a little confusion about accessing private inner classes of an object with the same object's methods. Here is the code of my excercise from Programming in Scala (pages 245-246):

import Element.elem

abstract class Element {
    def contents: Array[String]
    def height = contents.length
    def width = if(height == 0) 0 else contents(0).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 )
    }

    override def toString = contents mkString "\n"
 }


 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 (
            val ch: Character,
            override val width: Int,
            override val height: Int
    ) extends Element {
            private val line = ch.toString * width
            def contents = Array.fill(height)(line)
    }

    def elem(ss: Array[String]) = new ArrayElement(ss)
    def elem(s: String) = new LineElement(s)
    def elem(ch: Character, w: Int, h: Int) = new UniformElement(ch, w, h)

 }

The code is the same as in book, but the compiler complains about the three def elem() methods at the botton of the Element object. The error says:

private class ArrayElement escapes its defining scope as part of type pis.Code_c10s02_CompositionAndInheritance.Element.ArrayElement

however, if I remove the private modifier from the inner classes, everything becomes ok. This should not be the solution, seems this section of the book is essentially about privatizing classes inside an object. What is my mistake here?

1 Answer 1

13

For some reason it would rather fail the compile than infer a less specific but public type. Declare the elem methods with return type.

def elem(ss: Array[String]): Element             = new ArrayElement(ss)
def elem(s: String): Element                     = new LineElement(s)
def elem(ch: Character, w: Int, h: Int): Element = new UniformElement(ch, w, h)
Sign up to request clarification or add additional context in comments.

2 Comments

I have thought of that some more and there comes the next part of this question then: why the returned type has to be Element in each case and not the specific type that the method is used to create an object of? I think this is somehow related to the privacy/publicy but I cannot get the point... Is there any real meaning to it or is it a compiler quirk?
The type is private, so it is not visible outside its defining scope. It sounds like what you really want is a private constructor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.