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 asequals
final def !=(that: Any): Boolean
: asnot 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.