programacion - tipos de datos en scala
No puedo hacer ningĂșn paquete privado de clase en Scala? (3)
Lo siento por el título pegadizo. ;-)
Quiero crear una clase de paquete privado con un método de paquete privado en Scala, para que mi clase tenga este aspecto:
package net.java.truevfs.ext.pace
import ...
private[pace] abstract class AspectController(controller: FsController)
extends FsDecoratingController(controller) {
private[pace] def apply[V](operation: => V): V
... // lots of other stuff
}
Sin embargo, si uso javap para comprobar qué crea efectivamente el compilador de Scala, obtengo algo como esto:
$ javap -classpath target/classes net.java.truevfs.ext.pace.AspectController
Compiled from "AspectController.scala"
public abstract class net.java.truevfs.ext.pace.AspectController extends net.java.truevfs.kernel.spec.FsDecoratingController implements scala.ScalaObject{
public abstract java.lang.Object apply(scala.Function0);
...
}
Esto significa que aunque el compilador de Scala podría respetar las restricciones de acceso, aún podría llamar a esta clase desde cualquier código Java, lo que es una clara violación de encapsulación.
¿Me estoy perdiendo de algo? ¿Hay alguna manera de hacer que esto funcione como está previsto?
Además de la respuesta de @Régis, la razón por la que el compilador de Scala no hace que el paquete de clase sea privada es porque a través de las reglas de Scala se puede acceder desde otros paquetes: es decir, subpaquetes de net.java.truevfs.ext.pace
. P.ej
package net.java.truevfs.ext.pace.subpackage
import net.java.truevfs.ext.pace.AspectController
class Subclass extends AspectController { ... }
es legal en Scala, pero en las clases de Java de net.java.truevfs.ext.pace.subpackage
no se puede acceder a las clases privadas del net.java.truevfs.ext.pace
de net.java.truevfs.ext.pace
.
No es realmente una respuesta correcta al 100% ...
Puedes hacer un objeto de paquete si quiero hacer algunas cosas elegantes con una clase privada. Se accede al objeto del paquete como cualquier otro paquete. La clase MyClass es un paquete privado para ese objeto de paquete. Sin embargo, no es un paquete privado.
package object com.jasongoodwin.foo {
private class MyClass
class AnotherClass {
val myClass = new MyClass
}
}
Tu no te estas perdiendo nada. Muchas de las restricciones de acceso en scala no tienen equivalente en java ni en el nivel jvm. La información adicional obviamente está ahí en el archivo .class, pero hay anotaciones personalizadas que solo interpretará el compilador de Scala. El modelo de objetos de scala solo puede coincidir parcialmente con el modelo de objetos de jvm, y un compilador de java solo verá este modelo parcial. Yo diría que la coincidencia está bastante cerca y el compilador de scala hace un muy buen trabajo en la interoperabilidad de Java, pero nada es perfecto.