Scala: Declaring classes

Scala classes are public by default. It Java, to define a class with a field, you need to define the field an argument in the constructor for that field and an assignment from the argument to the field to initialise it. Scala allows you to declare it once and have it all done for you. For instance, the Java class:

public class ChangeRequest {
  public SocketChannel socket;
  public int type;
  public int ops;
  
  public ChangeRequest(SocketChannel socket, int type, int ops) {
    this.socket = socket;
    this.type = type;
    this.ops = ops;
  }
}

condenses to the Scala code:

class ChangeRequest(
    val socket: SocketChannel,
    val `type`: Int,
    val ops: Int) {
}

The backticks here are used to avoid Scala interpreting type as a keyword. The braces are optional if empty so the following would be fine as well.

class ChangeRequest(val socket: SocketChannel, val `type`: Int, val ops: Int)

We all want to declare something like this in our Scala ChangeRequest class:

  public static final int REGISTER = 1;
  public static final int CHANGEOPS = 2;

but Scala does not support static methods or fields because they don’t have OO semantics. Instead we define a singleton object of the same name as the class and add fields to that:

object ChangeRequest {
  val REGISTER = 1
  val CHANGEOPS = 2
}

There is not conflict between the class name and the object name because they are in different namespaces. Types always appear after the : or between the [] in Scala.

In Java you create a class with a class declaration, and in the class body, you put method and constructor declarations and in the method and constructor bodies you put your statements.

Scala is very similar except that your class body is also a constructor. Being a constructor means that statements can be placed in the class body and interleaved with field declarations. Scala will execute the class body as if it were a constructor from top to bottom. This is a clever way to reduce the amount of code. In Java it is typical to have to declare fields and initialise them in separate places, but in Scala it is much more readable as it is all in one place.

class NioServer(
    private val hostAddress: InetAddress,
    private val port: Int,
    private val worker: EchoWorker) extends Runnable {
  // The channel on which we'll accept connections
  // Create a new selector
  private val selector = SelectorProvider.provider().openSelector()

  // Create a new non-blocking server socket channel
  val serverChannel = ServerSocketChannel.open()
  serverChannel.configureBlocking(false)

  // Bind the server socket to the specified address and port
  val isa = new InetSocketAddress(this.hostAddress, this.port)
  serverChannel.socket().bind(isa)

  // Register the server socket channel, indicating an interest in 
  // accepting new connections
  serverChannel.register(selector, SelectionKey.OP_ACCEPT)

  // The buffer into which we'll read data when it's available
  private val readBuffer: ByteBuffer = ByteBuffer.allocate(8192)

  // A list of PendingChange instances
  private val pendingChanges: java.util.List[ChangeRequest] = new java.util.LinkedList[ChangeRequest]()

  // Maps a SocketChannel to a list of ByteBuffer instances
  private val pendingData: java.util.Map[SocketChannel, java.util.List[ByteBuffer]] =
    new java.util.HashMap[SocketChannel, java.util.List[ByteBuffer]]()

  // ... method declarations ...
}

In the above code hostAddress, port and worker are arguments to the NioServer constructor but also double as private immutable field declarations. In the class body selector, readBuffer, pendingChanges and pendingData are private fields while serverChannel and isa are public fields. Some statements are freely interleaved between these field declarations and all statements and field initialisations in the order that it would as if it were just normal code.

Additional constructors could be added, however all these if added would essentially delegate to the main constructor we have just declared after some performing some processing.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s