[Scala Level: A1]
Basically, access modifier in Scala is like other languages we are familiar with. They all use 'private', 'protected' and 'public' to identify differnct level of accessibility. However, there still some differences. Let's discover the difference in this section.
Difference of the access level
If there is no modifier specified, by default, the access level is public. As we've known, public members can be accessed from anywhere.
Scala's 'private' modifier is more strict than Java. In nested classes cases, private members of the nested class even cannot be accessed from the outer class.
class Outer {
private val privOuterStr = "I'm a private string in Outer"
class Nested {
private val privNestedStr = "I'm a private string in Nested"
println(privOuterStr) //can access privNestedStr
}
//println(privNestedStr) //cannot resolve symbol privNestedStr
}
In above example, 'privOuterStr' can be accessed from the Nested class, while 'privNestedStr' is in accessible from the Outer class.
Scala's 'protected' members are only allowed itself and its sub classes to access. In Java, protected members is also accessible from the same package.
Scope for modifiers
There is a more special point of Scala modifiers, which is, they can be attached with a scope, so that the member is accessible from the scope, such as private[this], protected[outer].
package outer {
package inner {
class Inner {
private val privateVal = "private can be accessed within the class"
private[this] val privateThis = "private[this], can only access from same object"
private[inner] val privateInner = "private inner, can access from the inner package"
private[outer] val privateOuter = "private outer, can access from the outer package"
def test() {
val another = new Inner
another.privateVal //OK
//another.privateThis //Inaccessible
}
}
object InInnerPackage {
def test() {
val inner1 = new Inner
inner1.privateInner //OK
//inner1.privateThis //Inaccessible
}
}
}
object InOuterPackage {
def test() {
val inner2 = new inner.Inner
inner2.privateOuter //OK
//inner1.privateInner //Inaccessible
//inner1.privateThis //Inaccessible
}
}
}
In above example, 'private[inner]', means the value is accessible in the whole inner package, while 'private[outer]' can be accessed from the outer package. Similarly, a scope can be assigned to protected members, such as 'protected[outer]', which means, it is accessible from the 'outer' package as well as from its sub classes.
NOTE
private[this] is a little different from private. private means its scope is class-wide, 'private' in above example equals to private[Inner], while the scope of private[this] is instance-wide. That's why 'another.privateThis' is inaccessible.
The code is available at Github