Mike Slinn

Deceptively Familiar: Access Modifiers

— Draft —

Published 2014-03-30. Last modified 2015-02-24.
Time to read: 2 minutes.

Scala's access modifiers seem much like Java's, however although they may look similar, the identical statements in each language mean different things. What's more, the documentation and implementation of Scala's access modifiers is incomplete. This lecture and code example show you the exact truth of the matter.

The sample code for this lecture can be found in courseNotes/src/main/scala/VisibilityDemo.scala.

In Scala you can define many levels of visibility for classes, objects, methods and properties. Visibility rules for Scala classes also apply to Scala objects.

There is no public keyword in Scala; however, by default classes, properties and methods all have public visibility. Scala public visibility means the same thing as Java public: software artifacts are visible in all valid scopes, for both languages.

The REPL cannot be used to test access visibility. The only way to know what really works is by compiling a Scala program.

Visibility Table

unadorned packageName className
protected protected – When applied to a Scala class, visibility is restricted to subclasses, and it is not visible from other classes in the defining package. When applied to a property or method, the property or method’s visibility is restricted to the defining Scala type and derived types. protected[packageName]protected and [scope] are additive, so protected[packageName] is accessible in subclasses as well as visible to all other classes in the specified package. When applied to a property or method, visibility is restricted to the defining Scala type and derived types in the specified package. protected[className] – The spec is blurry but the 2.10 implementation is equivalent to private. Best not to use this.
private private – Has same meaning in Scala and Java: class definitions and members are not visible from other classes.

private[packageName] – This is known as package-private, and is the default visibility for Java. However, the implementation is different between Scala and Java, and they do not interoperate properly.

Class or member is visible in the scope of packageName, which must enclose the class, either immediately or as a parent package.

Subclasses from other packages cannot access subclasses or members whose superclass was marked private[packageName].

private[className] – "package-private access without inheritance". The spec is blurry.

Class or member is visible in the scope of packageName, which must enclose the class, either immediately or as a parent package.

private[innerClassName] locks out the outer class.

The VisibilityDemo.scala program in the courseNotes project exercises all types of access visibility. All but the private class are defined with a group of properties and methods which exercise all non-deprecated visibilities. These members are named after their visibility so we can keep track of the many combinations of class and member visibilities. Most of these classes also define inner classes, again with varying visibility, and with names that suggest their visibility. All of the classes are defined in the com.micronautics.scalaIntro package or inner classes.

The private[this] and protected[this] access modifiers are deprecated and will be phased out.

The private[this] and protected[this] were poorly thought out and buggy. Few people used them as a result. Since that they have been deprecated, this course will not discuss them.

Primary Constructor Visibility

You can declare the default constructor as private or protected by inserting the appropriate keyword between the class name and the parameter list, like this:

Scala code
class Foo protected (arg1: MyType1, arg2: MyType2) { /* class body here */ }

... or:

Scala code
class Foo private (arg1: MyType1, arg2: MyType2) { /* class body here */ }

Syntax For Creating Inner Classes

Note the unique Scala syntax necessary to create instances of the inner Scala classes; the inner class name is qualified by the outer class instance which will contain the inner class instance.

Scala code
val publicInPublicInstance = new publicInstance.PublicInPublicClass

* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.