2012-01-05 15 views
8

Tengo una pequeña confusión sobre el acceso a las clases internas privadas de un objeto con los mismos métodos del objeto. Aquí está el código de mi ejercicio de programación en Scala (páginas 245-246):Ámbito privado del objeto Scala con clases internas y métodos

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) 

} 

El código es el mismo que en el libro, pero el compilador se queja de los tres métodos def elem() en el boton del objeto Element . El error dice:

ArrayElement clase privada escapa a su alcance como parte de la definición de tipo pis.Code_c10s02_CompositionAndInheritance.Element.ArrayElement embargo

, si quito el modificador private de las clases internas, todo se vuelve De acuerdo. Esta no debería ser la solución, parece que esta sección del libro trata esencialmente de privatizar clases dentro de un objeto. ¿Cuál es mi error aquí?

Respuesta

13

Por alguna razón, preferiría fallar en la compilación que inferir un tipo menos específico pero público. Declare los métodos elem con tipo de retorno.

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) 
+0

he pensado que un poco más y se llega a la siguiente parte de esta pregunta entonces: ¿por qué el tipo devuelto tiene que ser 'Element' en cada caso y no el tipo específico que se utiliza el método para crear una ¿objeto de? Creo que esto está relacionado de alguna manera con la privacidad/publicidad, pero no entiendo el punto ... ¿Tiene algún significado real o es un capricho del compilador? – noncom

+0

El tipo es privado, por lo que no es visible fuera de su ámbito de definición. Parece que lo que realmente quieres es un constructor privado. – extempore

Cuestiones relacionadas