Monday, 25 August 2014

Scala Note 18: Inner Classes

You want to create a class as an inner class to help keep the class out of your public API, or to otherwise encapsulate your code. In Scala it is possible to let classes have other classes as members. 

Such inner classes are members of the enclosing class in Java. However,  in Scala such inner classes are bound to the outer object.

For example, 


class Graph {
  class Node {
    var connectedNodes: List[Node] = Nil
    def connectTo(node: Node) {
      if (connectedNodes.find(node.equals).isEmpty) {
        connectedNodes = node :: connectedNodes
      }
    }
  }
  var nodes: List[Node] = Nil
  def newNode: Node = {
    val res = new Node
    nodes = res :: nodes
    res
  }
}

n1, and n2 are bound to graph g, while n3 is bound to graph h.


object IllegalGraphTest extends Application {
  val g: Graph = new Graph
  val n1: g.Node = g.newNode
  val n2: g.Node = g.newNode
  n1.connectTo(n2)      // legal
  val h: Graph = new Graph
  val n3: h.Node = h.newNode
  n1.connectTo(n3)      // illegal!
}

In Java the last line in the previous example program would have been correct. For nodes of both graphs, Java would assign the same type Graph.Node;

In Scala such a type can be expressed as well, it is written Graph#Node. If we want to be able to connect nodes of different graphs, we have to change the node type from "connectedNodes: List[Node] to connectedNodes: List[Graph#Node]"


Reference:
http://www.scala-lang.org/old/node/115.html



No comments:

Post a Comment