Tutorials
scala

Scala Traits

Learn about the use of traits in Scala with the help of syntactic examples.

DataCamp has recently launched there first Scala course: Introduction to Scala. Check it out!

You may also be interested in reading the following tutorials:

Introduction

A Trait is a concept pre-dominantly used in object-oriented programming, which can extend the functionality of a class using a set of methods.

Traits are similar in spirit to interfaces in Java programming language. Unlike a class, Scala traits cannot be instantiated and have no arguments or parameters. However, you can inherit (extend) them using classes and objects. Having said that, traits provide a specific set of methods/functions that execute behavior to a class and expect that the class implements a set of methods that then parameterize the provided behavior.

A trait that is used to define an object is created as a mixture of methods that can be used by different classes without requiring multiple inheritances. However, there can be outliers wherein two traits have a method with the same name (naming collision), which have to be used by a class, in which case the ambiguity has to be resolved explicitly.

Traits can have both abstract and non-abstract methods, fields as its members. When you do not initialize a method in a trait, then they are abstract, while the ones that are initialized are called non-abstract. In the abstract methods, the class that implements the trait takes care of the initialization.

Now, let's quickly understand Scala traits with the help of some examples!

Scala Trait Syntax

The syntax for the Scala trait is straightforward, it is defined by the keyword trait followed by the name of the trait.

trait Trait_Name{
// Variables
// Methods
}


As you can see from the above trait definition, a trait named DataCamp was defined, which has no variables and methods defined inside it.

Let's move onto a simple example of Scala traits, which will give you much more clarity on how they work programmatically.

As discussed in the introduction, the Scala Traits are inherited by a class using the extends keyword.

class Scala_Tutorial extends DataCamp{
// Variables
// Methods
}

Let's define a trait named Scala_Course, which will be inherited by the class DataCamp. Inside the trait, you will define an abstract method called scala(), which will be defined in the DataCamp class.

trait Scala_Course{  
    def scala()  
}  

class DataCamp extends Scala_Course{  
    def scala(){  
        println("DataCamp has recently launched there first Scala course")  
    }  
}  

object Main{  
    def main(args:Array[String]){  
        var a = new DataCamp()  
        a.scala()  
    }  
}

Now let us run the above code.


In the above example, the method scala() was an abstract method, and hence, the declaration was made in the class that inherited that trait.

But what if you have a method (non-abstract) which is already implemented in the trait? Well, in that case, the class which extends this trait need not implement the method which is already implemented in a trait.

Let's understand this with the help of a small example.

trait BMW{

    // trait variables
    var make: String = "BMW"
    var model: String = "X7"
    var fuel: Int = 40

    // trait method: NON-ABSTRACT
    def Display()
    {
        println("Make of the Car : " + make);
        println("Model of the Car : " + model);
        println("Fuel capacity of the Car : " + fuel);
    }
}


class Car extends BMW{
    // class variables
    var make1: String = "Mercedes Benz"
    var model1: String = "S350D"
    var fuel1: Int = 50

    // Class method
    def Merc_Specs()
    {
        println("Make of the Car : " + make1);
        println("Model of the Car : " + model1);
        println("Fuel capacity of the Car : " + fuel1);
    }
}

object Main  
{

    // Main method
    def main(args: Array[String])  
    {

        // Class object
        var obj = new Car();
        println("Calling the Class Method")
        obj.Merc_Specs();
        println("Calling the Trait Method")
        obj.Display();
    }
}

Let's run the above code:


Now that you have understood the difference between abstract and non-abstract methods, let's see what can go wrong when an abstract method is not implemented in the class that inherits or extends it.

Let us use the same example to understand this concept.

trait Scala_Course{  
    def scala()  
}  

class DataCamp extends Scala_Course{  
    def print(){  
        println("Error: Class DataCamp needs to be Abstract")  
    }  
}  

object Main{  
    def main(args:Array[String]){  
        var a = new DataCamp()  
        a.print()  
    }  
}

Running the above code results in an error, as shown below, since you did not define the trait method scala() (abstract) in the class that inherited it.


To make the above code work, there could be two possible solutions:

  • Define the scala() method in the class DataCamp or
  • Define the DataCamp class as abstract.

The last topic for today's tutorial is how you can inherit multiple traits in one class. So, let's quickly finish it up.

trait A{
// methods
}
trait B{
// methods
}
class C extends A with B{
}
trait BMW{


    var make: String = "BMW"
    var model: String = "X7"
    var fuel: Int = 40
}

trait Merc{


    var make1: String = "Mercedes Benz"
    var model1: String = "S350D"
    var fuel1: Int = 50


}



class Car extends BMW with Merc{

    def BMW_Specs()
    {
        println("Make of the Car : " + make);
        println("Model of the Car : " + model);
        println("Fuel capacity of the Car : " + fuel);
    }


    def Merc_Specs()
    {
        println("Make of the Car : " + make1);
        println("Model of the Car : " + model1);
        println("Fuel capacity of the Car : " + fuel1);
    }

}


object Main  
{

    // Main method
    def main(args: Array[String])  
    {

        // Class object
        var obj = new Car();
        println("Calling the BMW Trait")
        obj.BMW_Specs();
        println();
        println("Calling the Merc Trait")
        obj.Merc_Specs();
    }
}

Finally, let us run the above code.

Congratulations!

Congratulations on finishing this tutorial.

You now know what are Traits in programming and how to make use of it in Scala. One good exercise for you would be to find a solution for the abstract method when not defined in the class that inherited it. Try writing code for the same and see if the code runs without any compilation error. A small tip, you might want to look at Abstract Classes in Scala.

Please feel free to ask any questions related to this tutorial in the comments section below.

Finally, don't forget to take the new Scala course on DataCamp, Introduction to Scala.

Want to leave a comment?