Scala - Method Overriding



This chapter takes you through method overriding in Scala programming. A subclass can provide a specific implementation of a method that is already defined in its superclass.

Method Overriding

A subclass can provide a specific implementation of a method that is already defined in its superclass. So, the subclass can modify and extend the behavior of the method. You can achieve runtime polymorphism, where a single interface can be used for different underlying forms (data types).

Method overriding is the process by which a method in a subclass has the same name, return type, and parameters as a method in its superclass. But it provides a different implementation.

Syntax

The syntax of the method overriding is -

class SuperClass {
   def methodName(param1: Type1): ReturnType = {
   // Superclass implementation
   }
}

class SubClass extends SuperClass {
   override def methodName(param1: Type1): ReturnType = {
      // Subclass implementation
   }
}

Example

The following example demonstrates method overriding in Scala programming -

class Animal {
   def sound(): Unit = {
      println("Animal makes a sound")
   }
}

class Dog extends Animal {
   override def sound(): Unit = {
      println("Dog barks")
   }
}

object Demo {
   def main(args: Array[String]): Unit = {
      val animal: Animal = new Dog
      animal.sound()
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

Dog barks

In the example, Dog class overrides the sound method of the Animal class using the override keyword. Demo object shows polymorphism by creating an instance of Dog. But referencing it with an Animal type, calling the overridden sound method.

Rules for Method Overriding

1. override Keyword

You must use the override keyword when overriding a method. So, you can avoid accidental overriding and have readable code.

2. Method Signature

The method signature in the subclass must exactly match the method signature in the superclass. This includes the method name, return type, and parameter list.

3. Access Modifiers

The access level of the overriding method must be the same and less restrictive than the method in the superclass.

Method Overriding with Different Parameter Lists

While overriding a method, the subclass can have methods with different parameter lists. But to override, the method signature must exactly match the superclass method.

Example

The following example shows method overriding with different parameter lists Scala programming -

class Vehicle {
   def start(): Unit = {
      println("Vehicle is starting")
   }

   def start(key: String): Unit = {
      println(s"Vehicle is starting with key: $key")
   }
}

class Car extends Vehicle {
   override def start(): Unit = {
      println("Car is starting")
   }

   override def start(key: String): Unit = {
      println(s"Car is starting with key: $key")
   }
}

object Demo {
   def main(args: Array[String]): Unit = {
      val vehicle = new Vehicle()
      val car = new Car()

      vehicle.start()             // Vehicle is starting
      vehicle.start("VehicleKey") // Vehicle is starting with key: VehicleKey
      car.start()                 // Car is starting
      car.start("CarKey")         // Car is starting with key: CarKey
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

Vehicle is starting
Vehicle is starting with key: VehicleKey
Car is starting
Car is starting with key: CarKey

In the example, Car class overrides the start methods of the Vehicle class. Demo object shows how the overridden methods are called on instances of Vehicle and Car.

Overriding with Covariant Return Types

There can be method overriding with covariant return types, where the return type of the overriding method is a subtype of the return type of the overridden method.

Example

The following example shows method overriding with covariant return types in Scala programming -

class Animal {
   def create(): Animal = {
      println("Creating an Animal")
      new Animal
   }
}

class Dog extends Animal {
   override def create(): Dog = {
      println("Creating a Dog")
      new Dog
   }
}

object Demo {
   def main(args: Array[String]): Unit = {
      val animal = new Animal()
      val dog = new Dog()

      val newAnimal: Animal = animal.create() // Creates an Animal
      val newDog: Dog = dog.create()          // Creates a Dog
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

Creating an Animal
Creating a Dog

In the example, Dog class overrides the create method of the Animal class with a covariant return type. Demo object shows how the overridden method is called on instances of Animal and Dog.

Using Superclass Methods

You can call the superclass version of an overridden method using the super keyword. So you can access superclass method using super keyword.

Example

The following example shows how to access the superclass method using super keyword -

class Animal {
   def sound(): Unit = {
      println("Animal makes a sound")
   }
}

class Dog extends Animal {
   override def sound(): Unit = {
      super.sound()
      println("Dog barks")
   }
}

object Demo {
   def main(args: Array[String]): Unit = {
      val dog = new Dog
      dog.sound()
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

Animal makes a sound
Dog barks

In the example, Dog class overrides the sound method of the Animal class. It uses the super keyword to call the superclass version of the sound method before executing its own implementation.

Method Overriding Summary

  • A subclass to provide a specific implementation for a method defined in its superclass.
  • Overridden methods must have the same signature as the methods they override.
  • Method overriding supports polymorphism, code reusability, and dynamic binding.
  • There can be method overriding with covariant return types, where the return type of the overriding method is a subtype of the return type of the overridden method.
  • The method signature in the subclass must match the method signature in the superclass.
  • The super keyword can be used to call the superclass version of an overridden method.
  • You should use the override keyword for clarity and to avoid errors.
Advertisements