2010-11-25 14 views
8

Supongamos que tengo este código Scala:¿Por qué los miembros de mi objeto compañero anidado no son visibles automáticamente en la clase?

object Outer { 

    object Inner { 
    val B = "B" 
    } 
    class Inner { 
    def b = B 
    } 
} 

Yo esperaría que esto compilar, pero B no se puede acceder a partir de la definición de b. Necesito agregar import Inner._ en class Inner para hacerlo funcionar. ¿Porqué es eso? ¿El objeto complementario Inner no está definido correctamente?

+0

Vine aquí * otra vez * (después de haberlo olvidado), mostrando cuán importante puede ser este problema para los recién llegados. Creo que el 'Exterior' no juega ningún papel en la pregunta; es bastante igual incluso sin eso. Gracias por preguntar esto! – akauppi

Respuesta

6

Se supone que no debe funcionar de esta manera: usar import Inner._ es un comportamiento constante.


Generalmente, se necesita el objeto complementario, si desea lograr el comportamiento similar a los miembros estáticos en Java. forma Scala es mover todos los miembros estáticos de distancia a un objeto único, con la ventaja de que memebers privado/protegido de una clase compañera se puede acceder desde ella:

object Outer { 

    object Inner { 
    def print(inner: Inner) = inner.B // compiles! 
    }  
    class Inner { 
    private val B = "B" 
    }  
} 

Puede utilizar el objeto compañero como una fábrica para la clase con un constructor privado:

scala> object Outer { 
    | 
    | object Inner { 
    |  def newInstance = new Inner() 
    | } 
    | class Inner private() { 
    |  private val B = "B" 
    | } 
    | } 
defined module Outer 

scala> Outer.Inner.newInstance 
res1: Outer.Inner = [email protected] 

scala> new Outer.Inner 
<console>:7: error: constructor Inner cannot be accessed in object $iw 
     new Outer.Inner 
    ^
+0

Me gustaría definir B como una constante, usada en la clase Exterior.Inner y también accesible al mundo exterior como Outer.Inner.B. Tenía la impresión de que no necesitaba la importación si Inner no estaba anidado, pero veo que estaba equivocado, porque mi ejemplo tampoco compila si elimino la clase Outer ... Entonces, ¿cuál es el camino de las apuestas? para definir constantes, similar al 'static static final String B =" B ";' que escribiría en Java? –

+0

No veo un problema -> https://gist.github.com/715219 –

+0

OK, solo necesitaba la confirmación de que necesito la importación adicional. Eso está bien para mi; Solo estaba pensando que los miembros se importaron automáticamente en objetos/clases acompañantes. –

11

Si los miembros del objeto acompañante se pueden importar en la clase, sería contaminar el espacio de nombres de la clase sin que el programador controle ser capaz de ello. Esto podría no ser tan malo (pero todavía malo) con los valores, pero realmente no me gustaría ver eso con las funciones.

Solo piense en apply() o en las funciones que hereda de los rasgos (ambos casos donde no puede simplemente cambiar el nombre sin perder algo). Si estas funciones se importan automáticamente en el espacio de nombres de las clases, el compilador no sabría cuál usar. Entonces, si la clase y el objeto tenían una función func(), terminarían escribiendo this.func() en el código de las clases solo para asegurarse de cuál llamar.

Así que véalo como una posibilidad de mantener limpio su espacio de nombres. Todavía puedes contaminarlo usando import Inner._

+0

Buena justificación de por qué necesita la importación. Tiene mucho sentido. –

Cuestiones relacionadas