Scala provides a more granular access control if compared to Java. This post describes and shows how to implement each of the Scala access modifiers.
Scala has only two explicit access modifiers: private and protected, besides the implicit no modifier that defaults to public access.
However, we can qualify these modifiers to give them a finer-grained access control level.
The access levels from the most-restrictive to the less-restrictive are the following:
| Access level | Access modifier |
| Object-private | private[this] |
| Private | private |
| Protected | protected |
| Package-specific | private[your.package] |
| Public | no modifier |
This is the most restrictive access level, declared by qualifying the member as private[this]. Object-private members can only be called within the same instance:
class Bar {
private[this] def doSomethingVeryRestrictive(): Unit = {
println("Object-private method.")
}
def callVeryRestrictiveMethod(): Unit = {
doSomethingVeryRestrictive()
}
def cannotCallFromOtherObject(otherBar: Bar): Unit = {
otherBar.doSomethingVeryRestrictive() // Doesn't compile
}
} Declared with the private keyword. Similar to Java, Private members can be called only by the same class:
package com.bgasparotto.learningscala.accessmodifier
class Baz {
private def doSomethingPrivate(): Unit = {
println("Private method.")
}
def callPrivateMethod(otherBaz: Baz): Unit = {
otherBaz.doSomethingPrivate()
}
}
class NotBaz {
def cannotCallPrivateMethodFromOtherClass(baz: Baz): Unit = {
baz.doSomethingPrivate() // Doesn't compile
}
} Declared with the protected keyword. Unlike Java, protected members can be accessed only by subclasses, but not from other classes in the same package:
package com.bgasparotto.learningscala.accessmodifier
// Declares a protected method
class Boo {
protected def doSomethingProtected(): Unit = {
println("Protected method.")
}
} package com.bgasparotto.learningscala.accessmodifier.other
import com.bgasparotto.learningscala.accessmodifier.Boo
// Subclass of Boo (can be either on the same or different package)
class SubBoo extends Boo {
def callProtectedMethodHere(boo: Boo): Unit = {
doSomethingProtected()
}
def callProtectedMethodThere(boo: Boo): Unit = {
boo.doSomethingProtected()
}
} package com.bgasparotto.learningscala.accessmodifier
// Doesn't work: resides on the same package but it is not a subclass
class NotSubBoo {
def cannotCallProtectedMethodSamePackage(boo: Boo): Unit = {
boo.doSomethingProtected() // Doesn't compile
}
} Declared using a combination of the keyword private and the package level starting from the current location and optionally stepping-up the hierarchy.
In other words, the package-specific access level defines whether your type will be available only to members of the current package and its sub-packages, or to members of an upper-level package including its sub-packages as well:
package com.bgasparotto.learningscala.accessmodifier.other
class Fuz {
private[accessmodifier] def doSomethingAbroad(): Unit = {
println("Package-specific to packages [accessmodifier] and any of its sub-packages.")
}
private[other] def doSomethingFromPackage(): Unit = {
println("Package-private method (specific to [other])")
}
} The class Foz from the same package have access to all Fuz methods:
package com.bgasparotto.learningscala.accessmodifier.other
class Foz {
def callPackagePrivateMethod(fuz: Fuz): Unit = {
fuz.doSomethingAbroad()
}
def callBroaderPackageSpecificMethod(fuz: Fuz): Unit = {
fuz.doSomethingFromPackage()
}
} The class AnotherFuz can access only the method restricted to the accessmodifier package and its sub-packages, which this case is defined in accessmodifier.another:
package com.bgasparotto.learningscala.accessmodifier.another
import com.bgasparotto.learningscala.accessmodifier.other.Fuz
class AnotherFuz {
def callAccessibleMethod(fuz: Fuz): Unit = {
fuz.doSomethingAbroad()
}
def cannotCallTheOtherOne(fuz: Fuz): Unit = {
fuz.doSomethingFromPackage() // Doesn't compile
}
} And as expected, Faz which resides in an even higher package can’t access any methods:
package com.bgasparotto.learningscala
import com.bgasparotto.learningscala.accessmodifier.other.Fuz
class Faz {
def callAccessibleMethod(fuz: Fuz): Unit = {
fuz.doSomethingAbroad() // Doesn't compile
}
def cannotCallTheOtherOne(fuz: Fuz): Unit = {
fuz.doSomethingFromPackage() // Doesn't compile either
}
} Finally, when no access modifier is declared, the access level is set to public by default.
/* Public class given no access modifier was declared. */class Foo {
def doSomething(): Unit = {
println("Public method.")
}
} Unlike in Java, the keyword public is not reserved in Scala.
Hope it helps!
This guide will show you how to create a Python function decorator with a few…
This guide will show you how to fix the error Got permission denied while trying…
This guide will show you how to create a Python virtual environment on Intellij IDEA…
This tutorial will quickly show you how to to find and kill processes on Linux,…
This guide shows a possible solution for Python error Relocation R_X86_64_PC32 against symbol can not…
I condensed below a cheat sheet of Kubernetes useful commands. I will keep updating this…