Scala Access Modifiers
Scala access modifiers are essentially the same as those in Java, which include: private, protected, and public.
If no access modifier is specified, by default, the access level of Scala objects is public.
The private modifier in Scala is stricter than in Java. In the case of nested classes, the outer class cannot even access the private members of the nested class.
Private Members
Members marked with the private keyword are only visible within the class or object that contains the member definition, and the same rule applies to inner classes.
Example
class Outer{
class Inner{
private def f(){
println("f")
}
class InnerMost{
f() // Correct
}
}
(new Inner).f() // Error
}
The access (new Inner).f()
is illegal because f is declared as private within the class Inner, and the access is not within the class Inner.
However, accessing f within InnerMost is not a problem, as this access is contained within the class Inner.
Java allows both of these accesses because it allows the outer class to access the private members of the inner class.
Protected Members
In Scala, the access to protected members is stricter than in Java. It only allows protected members to be accessed within subclasses of the class that defined the member. In Java, members marked with the protected keyword can be accessed not only by subclasses of the class that defined the member but also by other classes in the same package.
Example
package p {
class Super {
protected def f() {println("f")}
}
class Sub extends Super {
f()
}
class Other {
(new Super).f() // Error
}
}
In the above example, the access to f by the Sub class is not a problem because f is declared as protected in Super, and Sub is a subclass of Super. Conversely, the access to f by Other is not allowed because Other does not inherit from Super. The latter is also recognized in Java because Other and Sub are in the same package.
Public Members
In Scala, if no modifier is specified, it defaults to public. Such members can be accessed from anywhere.
Example
class Outer {
class Inner {
def f() { println("f") }
class InnerMost {
f() // Correct
}
}
(new Inner).f() // Correct because f() is public
}
Scope Protection
In Scala, access modifiers can be emphasized by using qualifiers. The format is:
private[x]
or
protected[x]
Here, x represents a certain package, class, or singleton object. If it is written as private[x], it is read as "this member is private to all classes except those within [...] and their companion objects.
This technique is very useful in large projects that span several packages, allowing you to define something that is visible within several sub-packages of your project but always invisible to external clients.
Example
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
}
}
}
In the above example, the class Navigator is marked as private[bobsrockets], which means this class is visible to all classes and objects contained within the bobsrockets package.
For example, access to Navigator from the Vehicle object is allowed because the Vehicle object is contained within the launch package, and the launch package is within bobsrockets. Conversely, all code outside the package bobsrockets cannot access the class Navigator.