Scala - Nested Classes



This chapter takes you through the concept of nested classes in Scala programming. Nested classes are classes defined within other classes. These are useful for logically grouping classes that are only used in one place. So, nested classes increase encapsulation and reduce namespace pollution.

Nested Classes

Nested classes are classes defined inside other classes. These inner classes can access the members of the outer class. Nested classes are used in modeling relationships where one class logically belongs within another.

A nested class is a class defined within another class. The inner class can access the members (both fields and methods) of the outer class.

Syntax

The syntax of nested classes is -

class OuterClass {
  class InnerClass {
    // Class body
  }
  // Outer class body
}

Example

The following example shows a simple nested class in Scala programming.

class Outer {
  val outerValue = "Outer Value"

  class Inner {
    def display(): Unit = {
      println(s"Accessing from Inner Class: $outerValue")
    }
  }
}

object Demo {
  def main(args: Array[String]): Unit = {
    val outer = new Outer
    val inner = new outer.Inner
    inner.display()
  }
}

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

Command

\>scalac Demo.scala
\>scala Demo

Output

Accessing from Inner Class: Outer Value

In the example, the Outer class contains a nested class Inner. The Inner class has a method display that accesses a member of the Outer class. The Demo object creates instances of the Outer and Inner classes and calls the display method.

Inner Classes and Outer Class Instances

Each instance of an outer class has its own instance of the inner class. Inner class instance is tied to the outer class instance that created it.

Syntax

class OuterClass {
  class InnerClass {
    // Class body
  }
  // Outer class body
}

Example

The following example shows how inner class instances are tied to outer class instances.

class Outer(val outerValue: String) {
  class Inner {
    def display(): Unit = {
      println(s"Outer Value: $outerValue")
    }
  }
}

object Demo {
  def main(args: Array[String]): Unit = {
    val outer1 = new Outer("First Outer")
    val outer2 = new Outer("Second Outer")

    val inner1 = new outer1.Inner
    val inner2 = new outer2.Inner

    inner1.display()
    inner2.display()
  }
}

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

Command

\>scalac Demo.scala
\>scala Demo

Output

Outer Value: First Outer
Outer Value: Second Outer

In the example, each Outer class instance has its own Inner class instance. The display method of each Inner class instance accesses the outerValue of the corresponding Outer class instance.

Nested Classes with Private Members

Nested classes can access the private members of the outer class. So there is encapsulation with necessary functionality.

Syntax

class OuterClass {
  private val outerValue = "Outer Value"

  class InnerClass {
    def display(): Unit = {
      println(s"Accessing private member: $outerValue")
    }
  }
}

Example

The following example shows a nested class accessing a private member of the outer class.

class Outer {
  private val outerValue = "Outer Value"

  class Inner {
    def display(): Unit = {
      println(s"Accessing private member: $outerValue")
    }
  }
}

object Demo {
  def main(args: Array[String]): Unit = {
    val outer = new Outer
    val inner = new outer.Inner
    inner.display()
  }
}

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

Command

\>scalac Demo.scala
\>scala Demo

Output

Accessing private member: Outer Value

In the example, the Outer class has a private member outerValue. The nested Inner class can access this private member and use it in its display method. The Demo object creates instances of the Outer and Inner classes and calls the display method.

Nested Object

You can also define objects within classes. A nested object can be used to encapsulate related functionalities. This provides factory methods for the enclosing class.

Syntax

class OuterClass {
  object InnerObject {
    // Object body
  }
  // Outer class body
}

Example

The following example demonstrates a nested object in Scala programming.

class Outer {
  object Inner {
    def greet(): Unit = {
      println("Hello from Inner Object")
    }
  }
}

object Demo {
  def main(args: Array[String]): Unit = {
    val outer = new Outer
    outer.Inner.greet()
  }
}

Save the above program in Demo.scala. The following commands are used to compile and execute this program.

Command

\>scalac Demo.scala
\>scala Demo

Output

Hello from Inner Object

In the example, the Outer class contains a nested object Inner. The Inner object has a method greet that prints a message. The Demo object creates an instance of the Outer class and accesses the nested Inner object to call it greet method.

Scala Nested Classes Summary

  • Nested classes in Scala are classes defined inside other classes. So, there can be logical grouping and increased encapsulation.
  • Each instance of an outer class has its own instance of the nested inner class. So it creates a strong association between the two.
  • Nested classes can access the private members of the outer class. So provides tight encapsulation while maintaining functionality.
  • Nested objects can also be defined within class. So there can be encapsulating related functionalities and providing factory methods.
Advertisements