Scala notes III -- Classes and Objects

Classes and objects

In Scala, a class is a blueprint for objects. Once you define a class, you can create objects from the class blueprint with the keyword new. Through the object you can use all functionalities of the defined class.

An object is a named instance with members such as fields and methods. It is a class that has exactly one instance. There are three uses of objects.

  • Contain fields and methods that are independent of any environment;
object Math {
    def divide(x: Int, y: Int) = x / y
    def square(x: Int) = x*x
}

println(Math.square(3))
println(Math square 3)  // works if there is only one augment
  • Create instances of classes with the keyword new;
class Circle(radius: Double) {
  def area: Double = calculateArea(radius)
}

object Circle {
  private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0)
}

val circle1 = new Circle(5.0)
println(circle1.area)

An object with the same name as a class is called a companion object. Conversely, the class is the object’s companion class. A companion class or object can access the private members of its companion. Use a companion object for methods and values which are not specific to instances of the companion class.

  • Create the entry point to a Scala program by defining a main method with a specific signature.
object <object name> {
  def main(args: <arg type>) = {

  }
}
class User(var name: String, var age: Int);

object Demo {
  def main(args: Array[String]) {
    var user = new User("Max", 28);
    println(user.name);
    println(user.age);
    user.name = "Tom";  // rewritable because name is var
    user.age = 23;
    println(user.name);
    println(user.age);
  }
}

//          Getter?     Setter?
// -------  -------    ---------
// var        yes         yes
// val        yes         no
// default    no          no

// you cannot access name outside the class if it's private
class User2(private var name: String, var age: Int) {
  def printName{ println(name) }
};

var user2 = new User2("Max", 28);
println(user2.name); // returns error

// to access name inside a class
user2.printName

Class Hierarchies

Auxiliary constructor

An alternative constructor for a class.

With primary constructors, you must have different signatures for your auxiliary constructors; you must call previously defined constructors in your auxiliary constructors.

class User(val name: String, var age: Int) { // primary constructor
  def this() {  // auxiliary constructor
    this("Tim", 21);
  }

  def this(name: String) {
    this(name, 32);
  }
}

object Demo{
  def main(args: Array[String]) {
    var user1 = new User("Max", 28);
    var user2 = new User();
    var user3 = new User("Max");
  }
}

Class inheritance: extending a class

Scala doesn’t allow multiple inheritance from more than one class.

A super class Polygon:

package Inheritance

class Polygon {
  def area: Double = 0.0;
}

object Polygon {
  def main(args: Array[String]) {
    var poly = new Polygon;
    printArea(poly);

    var rect = new Rectangle(55.2, 20.0);
    printArea(rect);

    var tri = new Triangle(55.2, 20.0);
    printArea(tri);
  }

  def printArea(p: Polygon) {
    println(p.area);
  }    
}

A subclass Rectangle:

package Inheritance

class Rectangle(var width: Double, var height: Double) extends Polygon {
  override def area: Double = width * height; 
}

A subclass Triangle:

package Inheritance

class Triangle(var width: Double, var height: Double) extends Polygon {
  override def area: Double = width * height / 2; 
}

override redefines an existing, non-abstract definition in a subclass.

Abstract class

An abstract class can contain members which are missing an implementation. Consequently, it cannot be instantiated with the operator new.

An abstract class does a few things for the inheriting subclass:

  • define methods which can be used by the inheriting subclass;
  • define abstract methods which the inheriting subclass must implement, in another word, it makes sure that we must implement methods inside subclasses;
  • provide a common interface which allows the subclass to be interchanged with all other subclasses i.e. inheritance.
package Inheritance

abstract class Polygon {
  def area: Double; // doesn't provide any body to this method
}

object Polygon {
  def main(args: Array[String]) {
    // var poly = new Polygon;   // cannot be instantiated
    // printArea(poly);

    var rect = new Rectangle(55.2, 20.0);
    printArea(rect);

    var tri = new Triangle(55.2, 20.0);
    printArea(tri);
  }

  def printArea(p: Polygon) {
    println(p.area);
  }    
}

Trait

Scala doesn’t allow multiple inheritance and instead they use interface. A trait is a partially created interface.

package Inheritance

trait Shape {
  def shape: String;
}

class Rectangle(var width: Double, var height: Double) extends Polygon with Shape {
  override def area: Double = height * width;
  def shape: String = "rectangle";  // can remove override when inheriting from a trait
}
Avatar
Tingting Yu
Developer, Data Scientist

My research interests include time-series analysis, longitudinal analysis, image analysis …

Related