CSC 347 - Concepts of Programming Languages

Scala Classes

Instructor: Stefan Mitsch

Learning Objectives

Object-oriented programming

  • Understand basics of object-oriented programming in Scala

Scala Object-Oriented Programming

  • Scala supports both functional programming and object-oriented programming

Functional

  1. (0 to 9).toList.partition ((x:Int) => x%3 == 0)

Object-oriented

  1. class Counter:
  2. var n = 0
  3. def get () : Int = { val tmp = n; n = n + 1; tmp }
  4. val c = new Counter()
  5. c.get()
  6. c.get()

Classes

  • Define a class C
    1. class C (f1:Int, val f2:Int, var f3:Int):
    2. //...
  • Has one constructor with parameters f1, f2, f3
  • Instantiate the class C
    1. val c = new C (2, 3, 5)
  • Instance of C is heap allocated
  • c is a reference to instance

Class Parameters

  1. class C (f1:Int, val f2:Int, var f3:Int):
  2. //...
  • f1 private and immutable
  • f2 public immutable
  • f3 public mutable
  1. scala> val c = new C (2, 3, 5)
  2. c: C = C@8bd1b6a
  3. scala> c.f1
  4. <console>:10: error: value f1 is not a member of C
  5. scala> c.f2
  6. res1: Int = 3
  7. scala> c.f3
  8. res2: Int = 5
  9. scala> c.f2 = 10
  10. <console>:9: error: reassignment to val
  11. scala> c.f3 = 10
  12. c.f3: Int = 10

Class Parameter Details

  • Class parameters simultaneously declare constructors and accessor methods
  • Components of the class body are public by default

Scala

  1. class C1(x:Int):
  2. def double() = x+x

Expressed in Java

  1. public class C1 {
  2. private final int x;
  3. public C1(int x) {
  4. this.x = x;
  5. }
  6. public int double() {
  7. return x+x;
  8. }
  9. }

Class Parameter Details

  • Immutable class parameters can be initialized but not modified

Scala

  1. class C2(val x:Int):
  2. def double() = x+x

Expressed in Java

  1. public class C2 {
  2. private final int x;
  3. public C2(int x) {
  4. this.x = x;
  5. }
  6. public int x() {
  7. return x;
  8. }
  9. public int double() {
  10. return x+x;
  11. }
  12. }

Class Parameter Details

  • Mutable class parameters can be changed even after initialization

Scala

  1. class C3(var x:Int):
  2. def double() = x+x

Expressed in Java

  1. public class C3 {
  2. private int x;
  3. public C3(int x) { this.x = x; }
  4. public int x() { return x; }
  5. public void setX(int x) { this.x = x; }
  6. public int double() { return x+x; }
  7. }

Class Body

  • Class body contains
    • val or var field declarations
    • Constructor code
    • method definitions
  1. class C (f1:Int, val f2:Int, var f3:Int):
  2. val f4 = f1 * f2
  3. var f5 = f2 * f3
  4. println ("Constructing instance of C")
  5. def m (x:Int) : Int =
  6. // cannot reassign to f1, f2, f4
  7. f3 = f3 + 1
  8. f5 = f5 + 1
  9. f1 * f3 * x

Class Body

  • Can omit empty body
    1. class D (f1:Int)
  • Can omit empty parentheses
    1. class E:
    2. private var n:Int = 0
    3. def get () : Int =
    4. val tmp = n
    5. n = n + 1
    6. tmp
    7. val o : E = new E()
    8. o.get()

Objects

  • object declares a single instance, accessible through the object name
  • Language support for the singleton design pattern
  1. object C:
  2. var count:Int = 0
  3. C.count = C.count + 1

Objects

  • Singleton objects object are instantiated on program startup
  • Method main must be declared in an object

Java

  1. public class C {
  2. public static void main (String[] args) {
  3. //...
  4. }
  5. }

Scala

  1. object C:
  2. def main (args:Array[String]) : Unit =
  3. //...

Companion Objects

  • Many languages distinguish data and methods belonging
    • to an instance
    • to a class

Java

  • static components belong to a class
  • All other belong to an instance of the class
  1. class C {
  2. int f1;
  3. int m1 () { return f1; }
  4. static int f2;
  5. static int m2 () { return f2; }
  6. }

Scala: Companion object replaces static

  • All data and methods belong to objects
  • Companion object is related to other instances of the same class
  1. class C:
  2. var f1:Int = 0
  3. def m1 () : Int = f1
  4. object C:
  5. var f2:Int = 0
  6. def m2 () : Int = f2

Companion Objects

  • Companion objects can be used to construct instances of companion class
  • Implementation of the factory method design pattern
  • Companion can invoke private constructor
  1. class Point private (private var x:Int, private var y:Int):
  2. def translate (xDisp:Int, yDisp:Int) : Unit =
  3. x = x + xDisp
  4. y = y + yDisp
  5. object Point:
  6. def apply (x:Int, y:Int) : Point =
  7. if 0 <= x && x <= 10 && 0 <= y && y <= 10 then
  8. new Point (x, y)
  9. else
  10. throw IllegalArgumentException (s"Both x and y must be in range [0,10], but x=$x and y=$y.")
  1. // java.lang.IllegalArgumentException:
  2. // both x and y must be in range [0,10], but x=1 and y=100.
  3. val p = Point.apply (1, 100)
  4. // succeeds
  5. val q = Point.apply (1, 10)
  6. // name of "apply" method can be omitted
  7. val r = Point (1, 10)
  8. // compile error: constructor Point in class Point
  9. // cannot be accessed
  10. val s = new Point (1, 100)

Scala Library Companion Objects

  • Class List has a companion object
  1. object List extends SeqFactory[List] with Serializable:
  2. def apply[A](xs: A*): List[A] = ...
  3. //...other methods...
  4. List (1, 2, 3) // means List.apply (1, 2, 3)

Summary

  • Scala combines functional and object-oriented programming
  • Scala has builtin support for the Singleton design pattern
  • Scala has companion objects instead of static