Scala Classes

In support of object-oriented programming (OOP), Scala provides a class construct. The syntax is much more concise than languages like Java and C#, but it’s also still easy to use and read.

Basic class constructor

Here’s a Scala class whose constructor defines two parameters, firstName and lastName:

class Person(var firstName: String, var lastName: String)

Given that definition, you can create new Person instances like this:

val p = new Person("Bill", "Napper")

Defining parameters in a class constructor automatically creates fields in the class, and in this example you can access the firstName and lastName fields like this:

println(p.firstName + " " + p.lastName)
Bill Napper

In this example, because both fields are defined as var fields, they’re also mutable, meaning they can be changed. This is how you change them:

scala> p.firstName = "William"
p.firstName: String = William

scala> p.lastName = "Bernheim"
p.lastName: String = Bernheim

If you’re coming to Scala from Java, this Scala code:

class Person(var firstName: String, var lastName: String)

is pretty much the equivalent of this Java code:

public class Person {

    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

(I didn’t test that Java code. If I made a mistake with it, I hope I’m at least close.)

val makes fields read-only

In that first example I defined both fields as var fields:

class Person(var firstName: String, var lastName: String)

That makes those fields mutable. You can also define them as val fields, which makes them immutable:

class Person(val firstName: String, val lastName: String)
             ---                    ---

If you now try to change the first or last name of a Person instance, you’ll see an error:

scala> p.firstName = "Fred"
<console>:12: error: reassignment to val
       p.firstName = "Fred"
                   ^

scala> p.lastName = "Jones"
<console>:12: error: reassignment to val
       p.lastName = "Jones"
                  ^

Pro tip: If you use Scala to write OOP code, create your fields as var fields so you can easily mutate them. When you write FP code with Scala, you’ll general use case classes instead of classes like this. (More on this later.)

Class constructors

In Scala, the primary constructor of a class is a combination of:

  • The constructor parameters
  • Methods that are called in the body of the class
  • Statements and expressions that are executed in the body of the class

Fields declared in the body of a Scala class are handled in a manner similar to Java; they are assigned when the class is first instantiated.

This Person class demonstrates several of the things you can do inside the body of a class.

class Person(var firstName: String, var lastName: String) {

    println("the constructor begins")

    // 'public' access by default
    var age = 0

    // some class fields
    private val HOME = System.getProperty("user.home")

    // some methods
    override def toString(): String = s"$firstName $lastName is $age years old"

    def printHome(): Unit = {
        println(s"HOME = $HOME")
    }

    def printFullName(): Unit = { 
        println(this) 
    }

    printHome()
    printFullName()
    println("you've reached the end of the constructor")

}

This code in the Scala REPL demonstrates how this class works:

scala> val p = new Person("Kim", "Carnes")
the constructor begins
HOME = /Users/al
Kim Carnes is 0 years old
you've reached the end of the constructor
p: Person = Kim Carnes is 0 years old

scala> p.age
res0: Int = 0

scala> p.age = 36
p.age: Int = 36

scala> p
res1: Person = Kim Carnes is 36 years old

scala> p.printHome
HOME = /Users/al

scala> p.printFullName
Kim Carnes is 36 years old

Speaking from my own experience, this constructor approach felt a little unusual at first, but once I understood how it works I found it to be logical and convenient.

A note about the special procedure syntax

In that example I declared these two methods to return a Unit type:

def printHome(): Unit = {
    println(s"HOME = $HOME")
}

def printFullName(): Unit = { 
    println(this) 
}

That simply means that these methods don’t return anything; in this case they just print some output. Methods that don’t return anything are known as procedures. You can also use this special procedure syntax to declare procedures:

def printHome { println(s"HOME = $HOME") }

def printFullName { 
    println(this) 
}

Because these methods don’t have any input parameters and also have no return type, that’s a perfectly legal way to define these methods.

However, be aware that this syntax may go away in future Scala releases. (There’s a concern that this is a special syntax just to save a few characters of typing.)

Other Scala class examples

Here are a few other examples of simple Scala classes:

class Pizza (var crustSize: Int, var crustType: String)

// a stock, like AAPL or GOOG
class Stock(var symbol: String, var price: BigDecimal)

// a network socket
class Socket(val timeout: Int, val linger: Int) {
    override def toString = s"timeout: $timeout, linger: $linger"
}

class Address (
    var street1: String,
    var street2: String,
    var city: String, 
    var state: String
)

results matching ""

    No results matching ""