Modificadores de acceso en Scala

En Scala, los modificadores de acceso se utilizan para controlar la visibilidad y los permisos de acceso de clases, objetos, traits (rasgos) y sus miembros (como campos y métodos).

Los modificadores de acceso en Scala son básicamente iguales a los de Java: private, protected y public.

Si no se especifica un modificador de acceso, por defecto el nivel de acceso de los objetos Scala es public.

El modificador private en Scala es más estricto que en Java; en el caso de clases anidadas, la clase externa ni siquiera puede acceder a los miembros privados de la clase anidada.


Miembros privados (Private)

Modificados con la palabra clave private, los miembros marcados con este modificador solo son visibles dentro de la clase u objeto que contiene la definición del miembro; la misma regla se aplica a las clases internas.

Ejemplo

class Outer{
    class Inner{
        private def f(){
            println("f")
        }
        class InnerMost{
            f() // Correcto
        }
    }
    (new Inner).f() // Error
}

(new Inner).f( )El acceso no es válido porquefEstá declarado como private en Inner, y el acceso no está dentro de la clase Inner.

Pero en InnerMost, acceder afno hay problema, porque ese acceso está contenido dentro de la clase Inner.

Java permite ambos accesos, porque permite que la clase externa acceda a los miembros privados de la clase interna.


Miembros protegidos (Protected)

En Scala, el acceso a los miembros protegidos (Protected) es un poco más estricto que en Java, porque solo permite que los miembros protegidos sean accedidos en las subclases de la clase que define el miembro. En Java, además de las subclases de la clase que define el miembro, otras clases del mismo paquete también pueden acceder.

Ejemplo

package p {
    class Super {
        protected def f() {println("f")}
    }
    class Sub extends Super {
        f()
    }
    class Other {
        (new Super).f() // Error
    }
}

En el ejemplo anterior, el acceso de la clase Sub a f no tiene problema, porque f está declarado como protected en Super, y Sub es una subclase de Super. Por el contrario, el acceso de Other a f no está permitido, porque Other no hereda de Super. Este último caso también es permitido en Java, porque Other y Sub están en el mismo paquete.


Miembros públicos (Public)

En Scala, si no se especifica ningún modificador, el valor predeterminado es public. Estos miembros pueden ser accedidos desde cualquier lugar.

Ejemplo

class Outer {
   class Inner {
      def f() { println("f") }
      class InnerMost {
         f() // Correcto
      }
   }
   (new Inner).f() // Correcto porque f() es public
}

Acceso privado a nivel de paquete (Package-Private)

Scala también admite el modificador de acceso privado a nivel de paquete, que se utiliza para restringir que un miembro solo pueda ser accedido dentro de un paquete específico. Se puede lograr colocando la palabra clave private seguida de un nombre de paquete. El formato es:

private[x] 

o  

protected[x]

El private[x] aquíxse refiere a un paquete, clase u objeto singleton al que pertenece.

Si se escribeprivate[x], se lee como"Este miembro es private para todas las demás clases, excepto que es visible para las clases en […] o las clases en el paquete […] y sus objetos acompañantes."。

Esta técnica es muy útil en proyectos grandes que abarcan varios paquetes; te permite definir cosas que son visibles en varios subpaquetes de tu proyecto, pero que siguen siendo invisibles para los clientes externos al proyecto.

Ejemplo

package bobsrockets{
    package navigation{
        private[bobsrockets] class Navigator{
         protected[navigation] def useStarChart(){}
         class LegOfJourney{
             private[Navigator] val distance = 100
             }
            private[this] var speed = 200
            }
        }
        package launch{
        import navigation._
        object Vehicle{
        private[launch] val guide = new Navigator
        }
    }
}

En el ejemplo anterior, la clase Navigator está marcada como private[bobsrockets], es decir, esta clase es visible para todas las clases y objetos contenidos en el paquete bobsrockets.

Por ejemplo, el acceso a Navigator desde el objeto Vehicle está permitido, porque el objeto Vehicle está contenido en el paquete launch, y el paquete launch está dentro de bobsrockets. Por el contrario, todo el código fuera del paquete bobsrockets no puede acceder a la clase Navigator.


Objeto acompañante y clase acompañante

En Scala, el objeto acompañante y la clase acompañante pueden acceder mutuamente a los miembros privados del otro. El objeto acompañante y la clase acompañante son una clase y un objeto con el mismo nombre y en el mismo archivo.

Ejemplo

class CompanionExample {
  private val privateField: String = "I am private in class"
}

object CompanionExample {
  def accessPrivateField(example: CompanionExample): String = {
    example.privateField  // El objeto acompañante puede acceder a los miembros private de la clase
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val example = new CompanionExample
    println(CompanionExample.accessPrivateField(example))
  }
}
Otras extensiones