This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 4.16, “How to create inner classes in Scala.”
Problem
You want to create a Scala class as an inner class to help keep the class out of your public API, or to otherwise encapsulate your code.
Solution
Declare one class inside another class. In the following example, a case class named Thing
is declared inside of a class named PandorasBox
:
class PandorasBox { case class Thing (name: String) var things = new collection.mutable.ArrayBuffer[Thing]() things += Thing("Evil Thing #1") things += Thing("Evil Thing #2") def addThing(name: String) { things += new Thing(name) } }
This lets users of PandorasBox
access the collection of things inside the box, while code outside of PandorasBox
generally doesn’t have to worry about the concept of a Thing
:
object ClassInAClassExample extends App { val p = new PandorasBox p.things.foreach(println) }
As shown, you can access the things in PandorasBox
with the things
method. You can also add new things to PandorasBox
by calling the addThing
method:
p.addThing("Evil Thing #3") p.addThing("Evil Thing #4")
Discussion
The concept of a “class within a class” is different in Scala than in Java. As described on the official Scala website, “Opposed to Java-like languages where such inner classes are members of the enclosing class, in Scala, such inner classes are bound to the outer object.” The following code demonstrates this:
object ClassInObject extends App { // inner classes are bound to the object val oc1 = new OuterClass val oc2 = new OuterClass val ic1 = new oc1.InnerClass val ic2 = new oc2.InnerClass ic1.x = 10 ic2.x = 20 println(s"ic1.x = ${ic1.x}") println(s"ic2.x = ${ic2.x}") } class OuterClass { class InnerClass { var x = 1 } }
Because inner classes are bound to their object instances, when that code is run, it prints the following output:
ic1.x = 10 ic2.x = 20
There are many other things you can do with inner classes, such as include a class inside an object or an object inside a class:
object InnerClassDemo2 extends App { // class inside object println(new OuterObject.InnerClass().x) // object inside class println(new OuterClass().InnerObject.y) } object OuterObject { class InnerClass { var x = 1 } } class OuterClass { object InnerObject { val y = 2 } }
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |
See Also
- The Scala website has a page on Inner Classes