Scala Learning Series
Access Modifiers in Scala
Scala Programming
What is access modifiers in OOP?
Access modifiers, aka access specifiers, determine the scope or accessibility of classes, methods, and other members. The encapsulation principle of object-oriented programming is managed through the use of access modifiers.
Access specifiers are specified using the following keywords in general:
- Public
- Private
- Protected (derived classes and/or within the same package)
- Package
Any attempt at referencing an inaccessible member causes a compile-time error.
Scala’s access modifiers
Scala’s access modifiers mostly follow Java’s, but there are some important differences.
Public
Scala has no explicit modifier for public members. Any member not labelled private or protected is public, and hence all members are by default public. Public members can be accessed from anywhere.
Private
Private members in Scala are treated similarly to Java. A member labelled “private” is visible only to the current class/instance and also other instances of the same class that it’s declared in.
class MyClass {
private var myFlag: Boolean = false
def showMyVal(): Unit = {
println(myFlag) // No issue in accessing the private member
}
def showMyVal(other: MyClass) = {
// We can also access via other instance of current class
println(other.myFlag)
}
}
Private members are not available to sub-classes (refer below example).
class MyClass {
private var myFlag: Boolean = false
}
class MySubClass extends MyClass {
def myMethod(): Unit = {
// Note that private members are not available to sub-classes.
// Hence, the below statement won't compile as it is trying to
// access the private member, myFlag of the base class.
println(myFlag) // won't compile!
}
}
Object-private
Scala’s object-private takes privacy a step further than private scope and makes the fields and methods object-private. A definition labelled “private[this]"
is accessible only from within the same object that contains the definition.
private[this] def isMaxVal = true
Note that the other instances of the same class cannot access them.
class Cat {
var breed: String = "Persian"
private[this] var sex: String = "Male"
def showDetails(other: Cat): Unit = {
println(other.breed)
// Below statement won't compile as we are accessing
// via other instance of the same class.
//println(other.sex)
}
}
Protected
Accessing protected members in Scala is a bit more restrictive than in Java. In Java, protected members can be accessed by other classes in the same package, but this is not applicable to Scala.
In Scala, protected members can be accessible from:
- Within the class.
- Within its subclasses.
- Within the companion objects.
class MyBaseClass {
protected var myFlag: Boolean = false
def showFlag(): Unit = {
println("myFlag: " + myFlag) // Accessible from within the class
}
}
class MySubClass extends MyBaseClass {
def showDetails(): Unit = {
// Unlike private, we can access protected member from subclass.
println(myFlag)
}
}
Package or private[package]
To make a method available to all members of the current package, mark the method as being private to the current package by specifying it using the private[packageName]
syntax.
package org.earlycode.scalatutorial.basics {
class Fruit {
private[basics] def doChop {}
private def doEat {}
}
class PackageScope {
val fruitObj = new Fruit
// Access by other classes in the same package
// i.e. basics package.
fruitObj.doChop
// Below statement won't compile as doEat method is available
// only to the Fruit class
//fruitObj.doEat
}
}
Quick reference
Default access modifiers
Scala’s default access modifier is public. Note that there is no explicit modifier for public members — any member not labelled private or protected is public. Public members can be accessed from anywhere.
Differences and Similarities with Java
Differences
- Public — Unlike Java, Scala has no explicit modifier for public members.
- Protected members in Java have wider access than in Scala; Java’s protected members can be accessible not only from within the class or within its subclasses, but also from other classes in the same package.
- Default access modifier — Java defaults to package internal visibility, while Scala, on the other hand, defaults to public, i.e. can be accessed from anywhere.
- Java adopts an all-or-nothing access strategy, i.e., either it’s visible to all classes in the current package or it’s not visible to any, whereas Scala gives fine-grained control over visibility.
- Object-private scope — Scala
private[this]
takes privacy a step further than private scope and makes the fields and methods object-private which means they can only be accessed from the object that contains them.
Similarities
- Private members in Scala are treated similarly to Java.