Objects, classes, traits and case classes
Use the keyword class
class Foo
val foo = new Foo
Add a default constructor
class Foo {
val i = 1
def incr(i: Int) = this.i + i
}
val foo = new Foo
foo.i
foo.incr(2)
Reduce visibility of values with private
or protected
private val i = 1
private[this] val i = 1
private[mynamespace] val i = 1
protected val = i
protected[this] val = i
protected[mynamespace] val = i
Add constructor arguments
class Foo(currentValue: Int) {
def this() = this(0)
def incr(i: Int) = currentValue + i
}
Easy way
class Foo(var currentValue: Int)
val foo = new Foo(1)
foo.currentValue = 2
foo.currentValue
Accessor requires prefix _
class Foo(var _currentValue: Int) {
def currentValue = _currentValue
}
val foo = new Foo(1)
foo.currentValue
Scala way of mutator
class Foo(var _currentValue: Int) {
def currentValue = _currentValue
def currentValue_=(currentValue: Int) = _currentValue = currentValue
}
val foo = new Foo(1)
foo.currentValue = 2 ⇔ foo.currentValue_=(2)
Finally make the variable private.
Define trait like Java interface
trait Incrementable {
def currentValue: Int
def currentValue_=(i: Int): Unit
def incr(i: Int): Int = {
currentValue = currentValue + i
currentValue
}
}
trait Modifiable
Traits can be extended
class Foo(private var _currentValue: Int) extends Incrementable with Modifiable {
override def currentValue = _currentValue
override def currentValue_=(currentValue: Int) = _currentValue = currentValue
}
Objects are singletons. Scala has no static
, thus objects are used.
object Bar {
val foo = 0
}
Special case companion object
object Foo {
val defaultValue = 0 // can be accessed in class
def apply(currentValue: Int) = new Foo(currentValue)
}
val foo = Foo(1) ⇔ Foo.apply(1)
Now we have classes, with accessors and companion objects
class Bar(val _i: Int, val _j: Int) {
def i = _i
def j = _j
}
object Bar {
def apply(i: Int, j: Int) = new Bar(i, j)
}
val bar = Bar(0, 1)
bar.i
bar.j
We have seen pattern matching with Option
, thus write an unapply
method
object Bar {
def apply(i: Int, j: Int) = new Bar(i, j)
def unapply(bar: Bar): Option[(Int, Int)] = Some((bar.i, bar.j))
}
val bar = Bar(0, 1)
bar match {
case Bar(0, 1) => "bar"
case _ => "foo"
}
We can do simpler in Scala with case classes
case class Baz(i: Int, j: Int)
val baz = Baz(0, 1)
baz.i
baz.j
baz match {
case Baz(0, 1) => "baz"
case _ => "foo"
}
But there is more with case classes
val bazz = baz.copy()
baz == bazz
baz eq bazz
val bazzz = baz.copy(2)
Seq(baz, bazz, bazzz) filter {
case Baz(0, _) => true
case _ => false
}