Scala | Sealed Trait


Sealed provides exhaustive checking for our application. Exhaustive checking allows to check that all members of a sealed trait must be declared in the same file as of the source file. That means that all the possible known members of a trait that must be included are known by the compiler in advance. So this gives us advantage to prevent mistakes in our code.
Syntax :

sealed trait X{}
class A extends X
class B extends X
class C extends X

Exhaustive checking is mostly used in type / pattern matching in scala. Lets say we have a sealed trait X and classes that extends trait X. On matching sub-types of trait X we have to make sure that we inclusion of all known sub-types is a must. Below method would give us a warning.Though we would get the correct output, but this may could be lead to unexpected runtime crashes in our application.

Warning: match may not be exhaustive
def obj(item: X)= Z match{
   case A => //
   case B => //
}

Correct implementation would be like-

def obj(item: X)= Z match{
   case A => //
   case B => //
   case C => //
   or 
   case _ => //for covering all the remaining cases
}

Let us take a view on below program in file saves as language.scala:-
Example :

filter_none

edit
close

play_arrow

link
brightness_4
code

// Scala Program that illustrates sealed trait
// language.scala
sealed trait geeks
{
    val article="not done";
}
  
// Class extends trait
class scala extends geeks
{
    override val article ="scala article";
}
  
// Class extends trait
class java extends geeks
{
    override val article ="java article";
}
  
// Class extends trait
class csharp extends geeks
{
    override val article ="csharp article";
}
  
// Creating object
object GFG
{
    // Main method
    def main(args: Array[String])
    {
        val s = new scala;
        val j = new java;
        val c = new csharp;
        println(checkArticle(s));
        println(checkArticle(j));
        println(checkArticle(c));
    }
      
    // Defined function
    def checkArticle(Article: geeks): String = Article match
    {
        case s: scala =>s.article;
        case j: java =>j.article;
        case c: csharp =>c.article; 
                //exclusion of <strong>line 45</strong> would lead to warning
          
    }
}

chevron_right


Output :

scala article
java article
csharp article

 

some important points
  • Sub-types of a trait are known in advance- Not including any of the sub-type of sealed class C in pattern match would give us warning. Such a warning tells you that there’s a risk your code might produce a Match Error exception because some possible patterns are not handled. The warning points to a potential source of run-time faults, so it is usually a welcome help in getting your program right.
  • Sealed traits can only extend in the same source file as of sub-types- In above example, we have another class python in another scala file. Importing the trait geeks from language.scala we would get error message as below.
    illegal inheritance from sealed trait bag
    import geeks
    class python extends geeks{
        val article="python article";
    }
    
  • Sealed class is also mostly used in enums– Preventing illegal inheritance and using all the sub-type so to avoid exhaustive matching warnings.
    Example :

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // Scala Program that illustrates sealed trait
    // By using Enumeration
    sealed trait card extends Enumeration
      
    // Class extends trait
    case object CLUB extends card
      
    // Class extends trait
    case object HEART extends card
      
    // Class extends trait
    case object DIAMOND extends card
      
    // Class extends trait
    case object SPADE extends card
      
    // Creating object
    object obj1
    {   
        // Main method
        def main( args : Array[String])
        {
            val card1 = HEART;
            val card2 = CLUB;
            val card3 = SPADE;
            val card4 = DIAMOND;
            println(checkcard(card1))
            println(checkcard(card2))
            println(checkcard(card3))
            println(checkcard(card4))
        }
          
        // Defined function
        def checkcard(x: card): String = x match
        {
              
            case HEART =>"heart"
            case CLUB =>"club";
            case SPADE =>"spade";
            case DIAMOND =>"diamond"
        }
    }

    chevron_right

    
    

    Output :

    heart
    club
    spade
    diamond
    


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.