Polymorphism in Dart

Polymorphism is a core concept in object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. It enables a single interface to represent different underlying forms (data types). This flexibility allows for writing more generic and reusable code.

Key Concepts of Polymorphism

  1. Method Overriding: A derived class can provide a specific implementation of a method that is already defined in its parent class. The specific implementation is called at runtime based on the object type.
  2. Method Overloading: Although Dart does not support method overloading in the same way as some other languages, you can achieve similar behavior using optional parameters or named parameters.
  3. Dynamic Typing: Dart is a dynamically typed language, allowing objects to be assigned to variables of different types, enabling polymorphic behavior.

Types of Polymorphism

 

1. Compile-time Polymorphism (Static Polymorphism)

Compile-time polymorphism occurs when the method to be called is determined at compile time. In Dart, this is generally achieved through method overloading.

Example of Method Overloading Using Optional Parameters

dart

Copy

class Calculator {
  // Method with optional parameters   
  int add(int a, [int b = 0]) {
    return a + b;
  }
}

void main() {
  Calculator calc = Calculator();
  
  print(calc.add(5));       // Output: 5   
  print(calc.add(5, 10));   // Output: 15 
  }

Explanation

  • Optional Parameters: The add method can take one or two parameters. If the second parameter is not provided, it defaults to 0.

2. Runtime Polymorphism (Dynamic Polymorphism)

Runtime polymorphism is achieved through method overriding, where a derived class provides a specific implementation of a method defined in its base class.

Example of Method Overriding

class Animal {
  void sound() {
    print('Animal makes a sound');
  }
}

class Dog extends Animal {
  @override   
  void sound() {
    print('Dog barks');
  }
}

class Cat extends Animal {
  @override   
  void sound() {
    print('Cat meows');
  }
}

void makeSound(Animal animal) {
  animal.sound(); // Calls the appropriate sound method based on the object type 
  }

void main() {
  Animal myDog = Dog();
  Animal myCat = Cat();

  makeSound(myDog); // Output: Dog barks   
  makeSound(myCat); // Output: Cat meows 
  }

Explanation

  1. Base Class Method: The Animal class has a method sound().
  2. Overriding: The Dog and Cat classes override the sound() method to provide their specific implementations.
  3. Dynamic Method Resolution: The makeSound() function accepts an Animal type and calls the sound() method. At runtime, the appropriate method is executed based on the actual object type (Dog or Cat).

Advantages of Polymorphism

  1. Code Reusability: You can write code that works on the parent class type, but it will operate on any derived class type, promoting code reuse.
  2. Flexibility and Maintainability: Code can be easily expanded and maintained. Adding new derived classes requires minimal changes to existing code.
  3. Improved Design: Polymorphism helps in designing interfaces that can be used for different implementations, leading to cleaner and more organized code.

Conclusion

Polymorphism is a powerful feature in Dart that enhances the flexibility and extensibility of your code. By utilizing method overriding and optional parameters, you can create more generic and reusable components in your applications. Understanding and effectively implementing polymorphism will enable you to write cleaner, more maintainable code that can easily adapt to changing requirements.

PLAY QUIZ

What is polymorphism in the context of object-oriented programming?

The ability for a class to inherit from multiple classes.

The ability for objects of different classes to be treated as objects of a common superclass.

The ability to create multiple instances of a class.

The ability to define static methods within a class.