Закрытая область видимости объекта Scala с внутренними классами и методами - PullRequest
9 голосов
/ 05 января 2012

У меня небольшая путаница по поводу доступа к закрытым внутренним классам объекта с помощью тех же методов объекта. Вот код моего упражнения из программирования на Scala (страницы 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)

 }

Код такой же, как в книге, но компилятор жалуется на три def elem() метода у основания объекта Element. Ошибка говорит:

закрытый класс ArrayElement выходит за пределы определяющей области как часть типа pis.Code_c10s02_CompositionAndInheritance.Element.ArrayElement

однако, если я уберу модификатор private из внутренних классов, все станет хорошо. Это не должно быть решением, кажется, этот раздел книги посвящен приватизации классов внутри объекта. В чем здесь моя ошибка?

1 Ответ

14 голосов
/ 05 января 2012

По какой-то причине он скорее потерпит неудачу при компиляции, чем выведет менее конкретный, но публичный тип. Объявите методы elem с типом возвращаемого значения.

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)
...