Scala Tutorial - Learn How To Extend Multiple Traits

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

Overview

In this tutorial, we will learn how to create traits with type parameters and show how to have a class extend multiple traits by making use of the with keyword.

 

We will update the examples from the previous tutorials on Learn How To Create And Extend Trait and Learn How to Create Trait With Type Parameters.

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:

  • The trait is defined with type parameter DonutShoppingCartDao[A]. If you are unsure about type parameters, please review the previous tutorial.

2. Create a second trait which will define the methods for checking donut inventory

Next, we create another trait called DonutInventoryService[A] which encapsulates methods to query donut inventories such as checkStockQuantity() method.


println("\nStep 2: Create a second trait which will define the methods for checking donut inventory")
trait DonutInventoryService[A] {

 def checkStockQuantity(donut: A): Int

}

NOTE:

  • Trait DonutInventoryService[A] is also defined with type parameter.

3. Create a DonutShoppingCart class which extends multiple traits namely trait DonutShoppingCartDao and trait DonutInventoryService

We then define a class named DonutShoppingCart[A] which extends both the traits DonutShoppingCartDao[A]  and DonutInventoryService[A] as shown below.


println("\nStep 3: Create a DonutShoppingCart class which extends multiple traits namely trait DonutShoppingCartDao and trait DonutInventoryService")
class DonutShoppingCart[A] extends DonutShoppingCartDao[A] with DonutInventoryService[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
 }

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

NOTE:

  • We've made use of the with keyword to extend multiple traits.

4. Create an instance of DonutShoppingCart and call the add, update, search and delete methods

You can now create an instance of DonutShoppingCart and call the add, update, search and delete methods which were inherited from trait DonutShoppingCartDao[A]


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

NOTE:

  • To keep the example simple, we are passing a type of String although in a real world application you would most likely have custom type classes.

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


Step 4: Create an instance of DonutShoppingCart 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

 

5. Call the checkStockQuantity method which was inherited from trait DonutInventoryService

Since class DonutShoppingCart also extended the second trait DonutInventoryService[A], you also have access to the checkStockQuantity() method as shown below.


println("\nStep 5: Call the checkStockQuantity method which was inherited from trait DonutInventoryService")
donutShoppingCart.checkStockQuantity("Vanilla Donut")

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

Step 5: Call the checkStockQuantity method which was inherited from trait DonutInventoryService
DonutShoppingCart-> checkStockQuantity method -> donut: Vanilla Donut

This concludes our tutorial on Learn How To Extend Multiple Traits 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 second trait which will define the methods for checking donut inventory
  • Create a DonutShoppingCart class which extends multiple traits namely trait DonutShoppingCartDao and trait DonutInventoryService
  • Create an instance of DonutShoppingCart and call the add, update, search and delete methods
  • Call the checkStockQuantity method which was inherited from trait DonutInventoryService

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 use traits for Dependency Injection.

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