Traits As Stackable Modifications

Traits are similar to Java’s interfaces. Classes and objects can extend traits, but traits cannot be instantiated and hence have no parameters. It also supports multiple inheritance. Traits are created using trait keyword. 

Syntax: 

trait Trait_Name {
// Fields..
// Methods..
}

super keyword: It is used whenever a base and subclass have same-named methods so in order to resolve ambiguity we use the super keyword to call base class method. 

Stackable Modification with Traits 

Before, moving further first we should understand what is a Stackable Modification with the help of an example. Consider a customer who pays to Recharge his mobile phone to use mobile services such as voice calling, internet, etc. These services can be divided into different packages as per a particular user’s usage. If we want to implement this service we would be required to have the name of the package for which the customer has paid for a particular package, let’s say DataPack. So we can say the following. 

new Recharge with DataPack

Assuming that we have particular value in our Recharge class that has the list of services listed in a certain pack. What if the consumer wants to Recharge to one more pack, and we don’t want to have a mechanism that will explicitly modify the list of the services for us, but it should happen by default. This is like a behavior that is getting modified as we keep adding different packs. This kind of situation gets us know to the concept of stackable modifications. With the customer adds a new pack the list will keep on updating.



new Recharge with DataPack with FullTalkTime

Scala supports stackable modifications to any methods using classes or traits that means you can select a very specific behavior by stacking classes and traits by mixing them together. When you stack a new trait by overriding the same method over and over, then you will get a different or add-on behavior to your method.

The following example illustrates how traits can be stacked.

Example 1: 

In this example, we used traits to modify methods of a class by using traits in stackable fashion. Here, we use the super keyword to invoke dot() method in both the traits. In this way, we achieved stackable modification. In cases of stackable modification, the method invocation order is determined by linearization rule. 

Scala

filter_none

edit
close

play_arrow

link
brightness_4
code

// Scala program to illustrate traits 
// in stackable fashion
  
// Defining class shape
class Shape
{
  def dot(shape : String) = println("Dotted : " + shape)
}
  
// Using trait keyword
// Using super keyword
trait Square extends Shape 
{
  override def dot(shape : String) = super.dot("Square-" + shape)
}
  
// Using trait keyword
// Using super keyword
trait Circle extends Shape 
{
  override def dot(shape : String) = super.dot("Circle-" + shape)
}
  
// Using trait keyword
// Using super keyword
trait Sharp extends Shape
{
  override def dot(shape : String) = super.dot("Sharp-" + shape)
}
  
// Defining main
object Shapes 
{
  def main(args: Array[String]) 
  {
    val shape1 = new Shape with Sharp with Square
    shape1.dot("Shape-1"
  
    val shape2 = new Shape with Circle with Sharp
    shape2.dot("Shape-2"
}
}

chevron_right


Output: 

Dotted : Sharp-Square-Shape-1
Dotted : Circle-Sharp-Shape-2

Example 2: 

Scala

filter_none

edit
close

play_arrow

link
brightness_4
code

// Scala program to illustrate traits 
// in stackable fashion
  
// Defining class Ball
class Ball 
{
  def spin(ball : String) = println("Spinning : " + ball)
}
  
// Using trait keyword
// Using super keyword
trait Yellow extends Ball
{
  override def spin(ball : String) = super.spin("Yellow-" + ball)
}
  
// Using trait keyword
// Using super keyword
trait Blue extends Ball 
{
  override def spin(ball : String) = super.spin("Blue-" + ball)
}
  
// Using trait keyword
// Using super keyword
trait Shiny extends Ball 
{
  override def spin(ball : String) = super.spin("Shiny-" + ball)
}
  
// Defining main
object Balls
{
  def main(args: Array[String])
  {
    val ball1 = new Ball with Shiny with Yellow
    ball1.spin("Ball-1"
  
    val ball2 = new Ball with Blue with Shiny
    ball2.spin("Ball-2"
}
}

chevron_right


Output: 

Spinning : Shiny-Yellow-Ball-1
Spinning: Blue-Shiny-Ball-2




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.