top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

What is ‘scala trait’ in scala and When can you use traits?

+2 votes
485 views
What is ‘scala trait’ in scala and When can you use traits?
posted Jul 6, 2016 by Karthick.c

Share this question
Facebook Share Button Twitter Share Button LinkedIn Share Button

1 Answer

0 votes

Unlike class inheritance, in which each class must inherit from just one superclass, a class can mix in any number of traits. Traits are used to define object types by specifying the signature of the supported methods. Scala also allows traits to be partially implemented but traits may not have constructor parameters.

Using a trait like a Java interface

A trait can be used just like a Java interface. As with interfaces, just define the methods in your trait that you want extending

classes to implement:

trait BaseSoundPlayer {
  def play
  def close
  def pause
  def stop
  def resume
}

Extending traits

If a class implements one trait it will use the extends keyword:

class Mp3SoundPlayer extends BaseSoundPlayer {
  def play   {}
  def close  {}
  def pause  {}
  def stop   {}
  def resume {}
}

One trait can extend another trait:

trait Mp3BaseSoundFilePlayer extends BaseSoundFilePlayer {
  def getBasicPlayer:BasicPlayer
  def getBasicController:BasicController
  def setGain(volume: Double)
}

If a class extends a trait but does not implement the methods defined in that trait, it must be declared abstract:

// must be declared abstract because it does not implement BaseSoundPlayer methods

abstract class JavaSoundPlayer extends BaseSoundPlayer {
  def play   {}
  def close  {}
}

If a class implements multiple traits, it will extend the first trait (or a class, or abstract class), and then use with for other traits:

abstract class Animal {
  def speak
}

trait WaggingTail {
  def startTail
  def stopTail
}

trait FourLeggedAnimal {
  def walk
  def run
}

class Dog extends Animal with WaggingTail with FourLeggedAnimal {
  // implementation code here ...
}

Abstract and concrete fields in traits

In a trait, define a field with an initial value to make it concrete, otherwise give it no initial value to make it abstract:

trait PizzaTrait {
  var numToppings: Int     // abstract
  val maxNumToppings = 10  // concrete
}

In the class that extends the trait, you’ll need to define the values for the abstract fields, or make the class abstract. The Pizza class demonstrates how to override the numToppings field:

class Pizza extends PizzaTrait {
  var numToppings = 0      // override not needed
}

trait PizzaTrait {
  var numToppings: Int     // abstract
  val maxNumToppings = 10  // concrete
}

Using a trait like a Java abstract class

You can use traits like abstract classes in Java. In the following example, an implementation is provided for the speak method in the Pet trait, so implementing classes don’t have to override it. The Dog class chooses not to override it, while the Cat class does:

trait Pet {
  def speak { println("Yo") }   // concrete implementation of a speak method
  def comeToMaster              // abstract
}

class Dog extends Pet {
  // don't need to implement 'speak' if you don't want to
  def comeToMaster { ("I'm coming!") }
}

class Cat extends Pet {
  // override 'speak'
  override def speak { ("meow") }
  def comeToMaster { ("That's not gonna happen.") }
}

If a class extends a trait without implementing its abstract methods, it must be defined abstract. Because FlyingPet does not implement comeToMaster, it is defined abstract:

abstract class FlyingPet extends Pet {
  def fly { ("I'm flying!") }
}

Using traits as simple mixins

To implement a simple mixin, define the methods you want in your trait, then add the trait to your class using extends or with. In the following example we define a Tail trait:

trait Tail {
  def wagTail { println("tail is wagging") }
}

This trait can be used with an abstract Pet class to create a Dog:

abstract class Pet (var name: String) {
  def speak  // abstract
  def ownerIsHome { println("excited") }
}

class Dog (name: String) extends Pet (name) with Tail {
  def speak { println("woof") }
}

A Dog can now use the methods defined by both the abstract Pet class, as well as the Tail trait:

object Test extends App {
  val zeus = new Dog("Zeus")
  zeus.ownerIsHome
  zeus.wagTail
  zeus.speak
}

Limiting which classes can use a trait

You can limit a trait so it can only be added to classes which extend a specific subclass. To do this, use the “trait [TraitName] extends [SubclassName]” syntax. For instance, in the following example the Starship and WarpCore both extend the common superclass StarfleetComponent, so the WarpCore trait can be mixed into the Starship class:

class StarfleetComponent

trait WarpCore extends StarfleetComponent
class Starship extends StarfleetComponent with WarpCore
However, in the following example, the Warbird can’t extend the WarpCore trait because Warbird and WarpCore don’t share the same superclass:

class StarfleetComponent
trait WarpCore extends StarfleetComponent
class RomulanStuff
class Warbird extends RomulanStuff with WarpCore // won't compile
A trait inheriting a class is not a common occurrence, and in general the following approach is preferred.

You can mark your traits so they can only be used by subclasses of a certain type. To do this, begin your trait with the “this: LimitingType =>” statement, as shown here:

trait WarpCore {
  this: Starship =>
}

This next example shows that you can add a trait to an instance of a class (an object):

class DavidBanner

trait Angry {
  println("You won't like me ...")
}

object Test extends App {
  val hulk = new DavidBanner with Angry
}

Extending Java interfaces like Scala traits

You can extend Java interfaces like Scala traits. In your Scala application, just use the extends and with keywords to implement your Java interfaces:

// java
public interface Animal {
  public void speak();
}

public interface Wagging {
  public void wag();
}

public interface Running {
  public void run();
}

// scala
class Dog extends Animal with Wagging with Running {
  def speak { println("Woof") }
  def wag { println("Tail is wagging!") }
  def run { println("I'm running!") }
}
answer Aug 31, 2016 by Dominic
Similar Questions
+4 votes

Like Java’s Collection class, what is top level class/trait of Scala’s Collection API? Please explain the some high level hierarchy of Scala’s Collection API?

+4 votes

What is the main use of Option and Either in Scala? How do we handle Errors or Exceptions in Functional Style(FP style) in Scala?

...