Scala Access Modifiers
Access modifiers control the visibility of classes and their members in Scala. This chapter details public, private, protected, and package-private modifiers.
Basic Access Modifiers
Public Access
scala
object PublicAccess {
class PublicClass {
// Public fields (default)
val publicField = "public field"
// Public methods (default)
def publicMethod(): String = "Public method"
// Explicit public declaration
public def explicitPublicMethod(): String = "Explicitly public"
}
object PublicExample {
def main(args: Array[String]): Unit = {
val obj = new PublicClass()
println(s"Public field: ${obj.publicField}")
println(obj.publicMethod())
println(obj.explicitPublicMethod())
}
}
}Private Access
scala
object PrivateAccess {
class PrivateClass {
// Private fields
private val privateField = "private field"
// Private methods
private def privateMethod(): String = "Private method"
// Public method calling private
def accessPrivate(): String = {
privateField
s"Accessing private field: $privateField"
}
}
}
object PrivateExample {
def main(args: Array[String]): Unit = {
val obj = new PrivateClass()
// println(obj.accessPrivate())
}
}
}Protected Access
scala
object ProtectedAccess {
class Parent {
protected val protectedField = "protected field"
protected def protectedMethod(): String = "Protected method"
}
class Child extends Parent {
// Can access protected members
def accessProtected(): String = {
protectedMethod()
s"Accessing protected field: $protectedField"
}
}
}
object ProtectedExample {
def main(args: Array[String]): Unit = {
val child = new Child()
println(child.accessProtected())
}
}
}Package Private Access
scala
package com.example.scalanpackage
object PackageExample {
def publicMethod(): String = "Public method"
private privateMethod(): String = "Private method"
private[scala] packagePrivateMethod(): String = "Package private"
}Class Access Modifiers
Final Classes
scala
object FinalClasses {
final class ImmutableClass(val value: String) {
def getValue: String = value
}
object FinalExample {
def main(args: Array[String]): Unit = {
val immutable = new ImmutableClass("test")
println(immutable.getValue()) // Cannot override
}
}
}Sealed Classes
scala
object SealedClassExample {
sealed trait Status
case object Active extends Status
case object Inactive extends Status
def processStatus(status: Status): String = status match {
case Active => "System is active"
case Inactive => "System is inactive"
case _ => "Unknown status"
}
def main(args: Array[String]): Unit = {
println(processStatus(Active))
println(processStatus(Inactive))
}
}Companion Objects and Private Members
scala
object CompanionExample {
class Counter {
private var count = 0
def increment(): Unit = count += 1
def getCount: Int = count
}
object Counter {
def create(initialValue: Int): Counter = new Counter {
private var count = initialValue
def increment(): Unit = count += 1
def getCount: Int = count
}
}
def main(args: Array[String]): Unit = {
val counter = Counter.create(10)
println(s"Initial count: ${counter.getCount}")
counter.increment()
println(s"After increment: ${counter.getCount}")
val counter2 = new Counter(5)
println(s"Second counter: ${counter2.getCount}")
counter2.increment()
println(s"After increment: ${counter2.getCount}")
}
}
}Best Practices
Use default visibility:
- Make fields public by default
- Hide implementation details with private
Use protected wisely:
- For methods that need to be overridden
- For internal state that needs access in subclasses
Minimize visibility:
- Restrict access to what's necessary
- Use private for internal implementation
Use final when appropriate:
- For classes that shouldn't be extended
- For constants
Consider package private:
- For implementation details that don't need exposure outside package
- For package-internal utilities
Access modifiers are essential for encapsulation and information hiding in object-oriented programming.