YouTip LogoYouTip

Scala Access Modifiers

In Scala, access modifiers are used to control the visibility and accessibility of classes, objects, traits, and their members (such as fields and methods).

Scala's access modifiers are basically the same as Java's: private, protected, and public.

If no access modifier is specified, the default access level for Scala objects is public.

The private qualifier 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. 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 in Inner, and the access is not within the Inner class.

However, accessing f inside InnerMost is fine because the access is contained within the Inner class.

Java allows both kinds of access because it allows outer classes to access the private members of inner classes.


Protected Members

In Scala, access to protected members is stricter than in Java. It only allows access to protected members within subclasses of the class that defined the member. In Java, members marked with the protected keyword can be accessed by subclasses of the class that defined the member, as well as 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 example above, the Sub class's access to f is fine because f is declared as protected in Super, and Sub is a subclass of Super. Conversely, Other's access to f is not allowed because Other does not inherit from Super. The latter would be allowed in Java because Other and Sub are in the same package.


Public Members

In Scala, if no modifier is specified, the member is public by default. 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
}

Package-Private Access

Scala also supports package-private access modifiers, which restrict members to be accessible only within a specific package. This can be achieved by following the private keyword with a package name. The format is:

private or protected

Here, x stands for a package, class, or singleton object that the member belongs to.

If written as private, it is read as "this member is private to all classes except those in [...] or in the package [...] and their companion objects."

This technique is very useful in large projects that span several packages. It allows you to define something that is visible within several sub-packages of your project but remains invisible to external clients.

Example

package bobsrockets {
  package navigation {
    private class Navigator {
      protected def useStarChart() {}
      class LegOfJourney {
        private val distance = 100
      }
      private var speed = 200
    }
  }
  package launch {
    import navigation._
    object Vehicle {
      private val guide = new Navigator
    }
  }
}

In the example above, the class Navigator is marked as private, meaning this class is visible to all classes and objects contained within the bobsrockets package.

For instance, access to Navigator from the Vehicle object is allowed because the Vehicle object is contained in the launch package, and the launch package is within bobsrockets. Conversely, all code outside the bobsrockets package cannot access the Navigator class.


Companion Objects and Companion Classes

In Scala, companion objects and companion classes can access each other's private members. A companion object and a companion class are a class and an object with the same name in the same file.

Example

class CompanionExample {
  private val privateField: String = "I am private in class"
}

object CompanionExample {
  def accessPrivateField(example: CompanionExample): String = {
    example.privateField // Companion object can access the class's private member
  }
}

object Main {
  def main(args: Array): Unit = {
    val example = new CompanionExample
    println(CompanionExample.accessPrivateField(example))
  }
}
← Ng Ng ListNg Ng Keypress β†’