2. INTRODUCTION
➢
Traits in Scala are similar to interfaces, but much more powerful.
➢
A trait encapsulates method and field definitions, which can then be
reused by mixing them into classes.
➢
Unlike Java, Scala allows traits to be partially implemented; i.e. it is
possible to define default implementations for some methods.
➢
Once a trait is defined, it can be mixed in to a class using either the
“extends” or “with” keywords.
3. SIMPLE EXAMPLE USING EXTEND
trait Example {
def Test() {
println("Hello World!")
}
}
class Frog extends Example {
}
val frog = new Frog
frog.Test()
4. ➢
If you wish to mix a trait into a class that explicitly extends a
superclass, you use “extends” to indicate the superclass and
“with” to mix in the trait.
class Animal
class Frog extends Animal with Example {
override def toString = "green"
}
class Animal
trait HasLegs
class Frog extends Animal with Example with HasLegs {
override def toString = "green"
}
Traits
5. Thin versus rich interfaces
➢
Rich has many methods (easier in theory for client)
Clients can pick a method that exactly matches the functionality the
need.
➢
Thin has fewer – easier for implementer
Clients calling into a thin interface, however, have to write more code.
Traits can be used to create Rich Interfaces which are Thin, means traits
can have lot of methods- Many of them are implemented in terms of the
few unimplemented methods. So the class which mixes these traits
provides the implementation for the few unimplemented methods.
6. For Example:
class Point(val x: Int, val y: Int)
class Rectangle(val topLeft: Point, val bottomRight:
Point) extends Rectangular {
}
trait Rectangular {
def topLeft: Point
def bottomRight: Point
def left = topLeft.x
def right = bottomRight.x
def width = right - left
}
7. Cont....
val rect = new Rectangle(new Point(1, 1),new
Point(10,10))
println(rect.width)
Output: 9
8. THE ORDERED TRAIT
➢
The Ordered trait in Scala is typically used when defining a class
of objects that know how to order themselves by comparing
against other instances of that class.
For Example:
case class Rational(n: Int, d: Int) extends Ordered[Rational] {
def compare(that: Rational) =
(this.n * that.d) - (that.n * this.d)
}
It should return zero if the objects are the same, negative if receiver is
less than the argument, and positive if the receiver is greater than the
argument.
9. TRAITS WITH STACKABLE
MODIFICATIONS
Stackable traits in Scala refers to being able to mix in multiple
traits that work together to apply multiple modifications to a
method.
How It Works:
In this pattern, a trait (or class) can play one of three roles:
➢
The base: defines an abstract interface
➢
A core or a stackable: implement the abstract methods and
provides functionality
10. For Example:
abstract class IntQueue {
def get(): Int
def put(x: Int)
}
Now we’ll build a concrete class
import scala.collection.mutable.ArrayBuffer
class BasicIntQueue extends IntQueue {
private val buf = new ArrayBuffer[Int]
def get() = buf.remove(0)
def put(x: Int) { buf += x }
}
13. TO TRAIT, OR NOT TO TRAIT?
➢
If the behavior will not be reused, then make it a concrete
class. It is not reusable behavior after all.
➢
If it might be reused in multiple, unrelated classes, make it a
trait. Only traits can be mixed into different parts of the class
hierarchy.
➢
If you want to inherit from it in Java code, use an abstract class.
Because a Scala trait with only abstract members translates directly to a
Java interface.
14. References
➢
Programming in Scala, Martin Odersky
➢
A tour of Scala : Traits (see
http://www.scala-lang.org/node/126)
➢
www.artima.com/scalazine/articles/stackable_trait_patte
rn.html