Study note of the chapter 11, 12, 13 and 14 of the book: Programming In Scala, 4th Edition.

Chapter 11: Scala’s Hierarchy

The top of the hierarchy is class Any, it is a common superclass for all classes. It defines 6 methods:

  • final def ==(that: Any): Boolean: same as equals
  • final def !=(that: Any): Boolean: as not equals
  • def equals(that: Any): Boolean
  • def ##: Int: hash code.
  • def hashCode: Int
  • def toString: String

Any has two subclasses: AnyVal and AnyRef. AnyVal has 9 predefined value classes: Byte, Short, Int, Long, Char, Float, Double, Boolean, and Unit. Except Unit, all other 8 values are represented as Java’s primitive values. The instances are literals in Scala because the these class are both abstract and final. The Unit class only has one value ().

AnyRef is the base class of all reference classes in Scala. It is an alias for java.lang.Object. Use == or equals to compare two objects. Use eq or ne to compare reference equality.

At the bottom of the type hierarch are scala.Null and scala.Nothing. Null is a subclass of all reference classes. Type Nothing is at the very bottom of the hierarchy: it is a subtype of every other type. It has no values. It is often used as a return type of an error function, therefore the function can be called in any place because the result is a subclass of any type.

To define a value class, use a val parameter field and extends from AnyVal. Only method member is allowed, i.e., no field memebers.

It is a good practice to define a new class for each domain concept, even it is a tiny type: a type without any member.

Chapter 12: Traits

A trait encapsulates method and field definitions. It is used to provide a rich interface and stackable modification.

It has a default superclass of AnyRef and defines a new type. A class can mix in multiple traits. A mixed in trait is called a mixin.

Compared with an abstract class or a class, a trait 1) cannot have parameters 2) its super call is dynamic.

To make a stackable modificaiton, define abstract override method that calls a method of its super. A super call invokes the mothod in the next trait to itself. A linearization process determines the method calls.

Usually, prefer a trait over a class.

Chapter 13: Packages and Imports

Scala packages can be defined in three approaches: package x.y, package x { pacckage y {}} and pacakge x; package y.

Use __root__ to specify root level packages.

import can be anywhere, may refer to objects (singleton or regular), rename/hide/match-all (x => y, x => _ and x._).

The protected[X] and private[X] specify scope of protection where the scope can be enclosing package, class or singleton object. private[this] guarantees that it is not accessible from other objects of the same class. Companion object and class share the same access right.

Chapter 14: Assertions and Tests

assert and ensuring throw AssertionError if its condition doesn’t hold. Use -ea or -da to enable or disable assertions.

ScalaTest is a flexible test framework that use suite to declare lifecycle methods of test runs. ScalaTest offers style traits that extends Suite trait and overrides lifecycle methods to support different testing styles. It also proivdes mixin traits that override lifecycle methods.

It integrates with behavior-driven development (BDD) such as AnyFlatSpec or a test framework such as specs2. It also integrate with ScalaCheck, a property-based testing library.