Scala Tutorial - Learn How To Create Trait With Type Parameters

By Nadim Bahadoor | Last updated: July 25, 2017 at 14:26 pm

Overview

In this tutorial, we will learn how to create trait with type parameters which defines methods that a consuming class should implement. This is similar to implementing a generics interface if you come from an Object Oriented background and have used Java or .NET in the past.

 

We will update the examples from the previous tutorial on Learn How To Create And Extend Trait by adding type parameter to the trait DonutShoppingCartDao.

Steps

1. Create a trait which will define the methods for a data access layer

Let's start with defining a simple trait called DonutShoppingCartDao and it will provide the method signatures to represent a Data Access Layer.


println("Step 1: Create a trait with type which will define the methods for a data access layer")
trait DonutShoppingCartDao[A] {

 def add(donut: A): Long

 def update(donut: A): Boolean

 def search(donut: A): A

 def delete(donut: A): Boolean

}

NOTE:

  • You create a trait in Scala by making use of the keyword trait.
  • DonutShoppingCartDao expects a type parameter which we've defined using the syntax trait DonutShoppingCartDao[A] {...}
  • The method signatures also make use of the type parameter A

2. Create a DonutShoppingCart class of type A which extends the trait from Step 1 and implements its methods

If you have used another programming language like Java or .NET in the past, you should be familiar with using the extends keyword to implement an interface. Similarly, to implement the trait DonutShoppingCartDao from Step 1, you will need to make use of the extends keyword.


println("\nStep 2: Create a DonutShoppingCart class of type A which extends the trait from Step 1 and implements its methods")
class DonutShoppingCart[A] extends DonutShoppingCartDao[A] {

 override def add(donut: A): Long = {
  println(s"DonutShoppingCart-> add method -> donut: $donut")
  1
 }

 override def update(donut: A): Boolean = {
  println(s"DonutShoppingCart-> update method -> donut: $donut")
  true
 }

 override def search(donut: A): A = {
  println(s"DonutShoppingCart-> search method -> donut: $donut")
  donut
 }

 override def delete(donut: A): Boolean = {
  println(s"DonutShoppingCart-> delete method -> donut: $donut")
  true
 }
}

NOTE:

  • Since DonutShoppingCartDao expects a type parameter, we've also define a type class DonutShoppingCart with a type parameter using the syntax DonutShoppingCart[A]

3. Create an instance of DonutShoppingCart of type String and call the add, update, search and delete methods

We can now create an instance of DonutShoppingCart and call the corresponding add, update, search and delete methods. For simplicity, we are passing a type of String to DonutShoppingCart whereas in a real application you would perhaps have a custom type of Donut.


println("\nStep 3: Create an instance of DonutShoppingCart of type String and call the add, update, search and delete methods")
val donutShoppingCart1: DonutShoppingCart[String] = new DonutShoppingCart[String]()
donutShoppingCart1.add("Vanilla Donut")
donutShoppingCart1.update("Vanilla Donut")
donutShoppingCart1.search("Vanilla Donut")
donutShoppingCart1.delete("Vanilla Donut")

You should see the following output when you run your Scala application in IntelliJ:


Step 3: Create an instance of DonutShoppingCart of type String and call the add, update, search and delete methods
DonutShoppingCart-> add method -> donut: Vanilla Donut
DonutShoppingCart-> update method -> donut: Vanilla Donut
DonutShoppingCart-> search method -> donut: Vanilla Donut
DonutShoppingCart-> delete method -> donut: Vanilla Donut

 

4. Create an instance of DonutShoppingCart of type String and assign its type to the trait DonutShoppingCartDao

Since our DonutShoppingCart class extended the trait DonutShoppingCartDao, you can also assign the type of the DonutShoppingCart object to the trait DonutShoppingCartDao as follows:


println("\nStep 4: Create an instance of DonutShoppingCart of type String and assign its type to the trait DonutShoppingCartDao")
val donutShoppingCart2: DonutShoppingCartDao[String] = new DonutShoppingCart[String]()
donutShoppingCart2.add("Vanilla Donut")
donutShoppingCart2.update("Vanilla Donut")
donutShoppingCart2.search("Vanilla Donut")
donutShoppingCart2.delete("Vanilla Donut")

NOTE:

  • You have to specify a type of String using the syntax DonutShoppingCartDao[String] because trait DonutShoppingCartDao[A] expects a type parameter.

You should see the following output when you run your Scala application in IntelliJ:


Step 4: Create an instance of DonutShoppingCart of type String and assign its type to the trait DonutShoppingCartDao
DonutShoppingCart-> add method -> donut: Vanilla Donut
DonutShoppingCart-> update method -> donut: Vanilla Donut
DonutShoppingCart-> search method -> donut: Vanilla Donut
DonutShoppingCart-> delete method -> donut: Vanilla Donut

This concludes our tutorial on Learn How To Create Trait With Type Paramters and I hope you've found it useful!

 

Stay in touch via Facebook and Twitter for upcoming tutorials!

 

Don't forget to like and share this page :)

Summary

In this tutorial, we went over the following:

  • Create a trait which will define the methods for a data access layer
  • Create a DonutShoppingCart class of type A which extends the trait from Step 1 and implements its methods
  • Create an instance of DonutShoppingCart of type String and call the add, update, search and delete methods
  • Create an instance of DonutShoppingCart of type String and assign its type to the trait DonutShoppingCartDao

Tip

  • We've kept the trait type parameters example simple but it would be good to review variance namely covariance and contra-variance type parameters.
  • In upcoming tutorials in this Chapter, we will also show how to use traits to build some pure Functional Programming constructs such as Monoids and Functors and much more!

Source Code

The source code is available on the allaboutscala GitHub repository.

 

What's Next

In the next tutorial, I will show you how to extend Multiple Traits.

Nadim Bahadoor on FacebookNadim Bahadoor on GithubNadim Bahadoor on LinkedinNadim Bahadoor on Twitter
Nadim Bahadoor
Senior Software Developer | Nephila Capital
Founder of allaboutscala.com. I have over 10 years of experience in building large scale real-time trading systems in the financial industry. Passionate about Distributed Systems, Scala, Big Data and Functional Programming. Stay in touch for upcoming tutorials!
Other allaboutscala.com tutorials you may like:

Share this article on