Scala Tutorial

Basics

Control Statements

OOP Concepts

Parameterized - Type

Exceptions

Scala Annotation

Methods

String

Scala Packages

Scala Trait

Collections

Scala Options

Miscellaneous Topics

Calling A Super Class Constructor in Scala

In Scala, when you create an instance of a subclass, the constructor of its superclass is called before the subclass's constructor. If the superclass has multiple constructors, by default the primary (no-argument) constructor is invoked. But what if you want to call a specific superclass constructor with arguments? You can do that by placing the arguments right after the extends keyword.

Here's how you can call a superclass constructor in Scala:

  1. Basic Example:

    class Parent(val name: String) {
      println(s"Parent constructor with name $name")
    }
    
    class Child(name: String, val age: Int) extends Parent(name) {
      println(s"Child constructor with name $name and age $age")
    }
    
    val child = new Child("John", 10)
    // Output:
    // Parent constructor with name John
    // Child constructor with name John and age 10
    

    In the above example, the Child class's constructor takes two parameters. It passes one of them (name) to the Parent class's constructor using extends Parent(name).

  2. Chained and Auxiliary Constructors:

    If you have auxiliary constructors (secondary constructors) in your Scala classes, the first statement in every auxiliary constructor must either call the primary constructor (of the same class) or another auxiliary constructor.

    Similarly, the superclass constructor is still only directly called from the primary constructor. If you're invoking the superclass constructor with specific arguments, ensure those arguments are available when the primary constructor is executed.

    class Parent(val name: String) {
      def this() = {
        this("Unknown")
        println("Parent auxiliary constructor")
      }
      println(s"Parent primary constructor with name $name")
    }
    
    class Child(name: String, val age: Int) extends Parent(name) {
      def this(age: Int) = {
        this("Unknown Child", age)
        println("Child auxiliary constructor")
      }
      println(s"Child primary constructor with name $name and age $age")
    }
    
    val child = new Child(15)
    // Output:
    // Parent primary constructor with name Unknown Child
    // Child primary constructor with name Unknown Child and age 15
    // Child auxiliary constructor
    

In conclusion, when you're subclassing in Scala, you can easily pass arguments to the superclass's constructor by placing them right after the extends keyword. Ensure you understand the order of constructor execution, especially when auxiliary constructors are involved.

  1. Using super keyword to call a constructor in Scala:

    • Description: The super keyword is used to call a constructor from the superclass when creating an instance of a subclass.
    • Code Example:
      class Animal(name: String) {
        println(s"Creating animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name) {
        println(s"Creating $breed dog named $name")
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  2. Scala super() constructor invocation:

    • Description: In Scala, the super() constructor invocation is implicit and is called automatically when creating an instance of a subclass.
    • Code Example:
      class Animal(name: String) {
        println(s"Creating animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name) {
        println(s"Creating $breed dog named $name")
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  3. Invoking parent class constructor in Scala:

    • Description: The super keyword is used to invoke the constructor of the parent class during the creation of a subclass instance.
    • Code Example:
      class Animal(name: String) {
        println(s"Creating animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name) {
        println(s"Creating $breed dog named $name")
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  4. Scala constructor chaining with super:

    • Description: Constructor chaining involves calling one constructor from another using the super keyword.
    • Code Example:
      class Animal(name: String, category: String) {
        def this(name: String) = this(name, "Generic")
      }
      
      class Dog(name: String, breed: String) extends Animal(name) {
        def this(name: String) = this(name, "Unknown")
      
        println(s"Creating $breed dog named $name")
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  5. Overriding and calling superclass constructors in Scala:

    • Description: When overriding a method and calling the superclass constructor, super is used to invoke the parent class constructor.
    • Code Example:
      class Animal(name: String) {
        println(s"Creating animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name) {
        override def toString: String = s"${super.toString}, Breed: $breed"
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  6. Calling base class constructor in Scala:

    • Description: The base class constructor is called using super when creating an instance of a subclass.
    • Code Example:
      class Animal(name: String) {
        println(s"Creating animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name) {
        println(s"Creating $breed dog named $name")
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  7. Scala auxiliary constructor and super:

    • Description: Auxiliary constructors in Scala can use super to invoke another constructor within the same class.
    • Code Example:
      class Animal(name: String, category: String) {
        def this(name: String) = this(name, "Generic")
      }
      
      class Dog(name: String, breed: String) extends Animal(name) {
        def this(name: String) = {
          this(name, "Unknown")
          println(s"Creating $breed dog named $name")
        }
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  8. Using super in constructor parameters in Scala:

    • Description: super can be used in constructor parameters to pass arguments to the superclass constructor.
    • Code Example:
      class Animal(name: String, category: String) {
        println(s"Creating $category animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name, "Canine") {
        println(s"Creating $breed dog named $name")
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  9. Mixins and calling constructors from supertraits in Scala:

    • Description: When using mixins, super is used to call constructors from supertraits.
    • Code Example:
      trait Animal {
        println("Creating Animal")
      }
      
      trait Pet extends Animal {
        println("Creating Pet")
      }
      
      class Dog extends Pet {
        println("Creating Dog")
      }
      
      val myDog = new Dog
      
  10. Accessing protected constructors in Scala:

    • Description: Constructors can be marked as protected to limit access. super is used to invoke a protected constructor in a subclass.
    • Code Example:
      class Animal protected (name: String) {
        println(s"Creating animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name) {
        println(s"Creating $breed dog named $name")
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  11. Chaining constructors with super in Scala:

    • Description: Constructor chaining involves calling one constructor from another using super, allowing for flexible initialization.
    • Code Example:
      class Animal(name: String, category: String) {
        println(s"Creating $category animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name, "Canine") {
        def this(name: String) = {
          this(name, "Unknown")
          println(s"Creating unnamed dog named $name")
        }
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  12. Constructor delegation in Scala:

    • Description: Constructor delegation involves using auxiliary constructors or other constructors to share common initialization logic.
    • Code Example:
      class Animal(name: String, category: String) {
        println(s"Creating $category animal named $name")
      }
      
      class Dog(name: String, breed: String) extends Animal(name, "Canine") {
        def this(name: String) = {
          this(name, "Unknown")
          println(s"Creating unnamed dog named $name")
        }
      }
      
      val myDog = new Dog("Buddy", "Labrador")
      
  13. Scala primary and auxiliary constructor usage with super:

    • Description: Primary constructors and auxiliary constructors can both use super to delegate to another constructor within the same class.
    • Code Example:
      class Animal(name: String, category: String) {
        println(s"Creating $category animal named $name")
      
        def this(name: String) = {
          this(name, "Generic")
          println(s"Creating unnamed animal named $name")
        }
      }
      
      val myAnimal = new Animal("Fido")