How to Implement Polymorphism in Dart

Polymorphism is a core concept in object-oriented programming that allows objects of different classes to be treated as objects of a common superclass. In Dart, polymorphism can be achieved through method overriding and interfaces. This enables you to write more flexible and reusable code by allowing different classes to provide specific implementations of methods defined in a common interface or superclass.

1. Method Overriding

Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. This allows the subclass to customize the behavior of the method while still maintaining the same method signature.

Example of Method Overriding

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

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

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

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

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

In this example, the Animal class defines a method speak. The Dog and Cat classes override this method to provide their specific implementations. In the main function, we create instances of Dog and Cat but reference them as Animal. When we call the speak method, the appropriate implementation is executed based on the actual object type.

2. Using Interfaces

Polymorphism can also be achieved through interfaces. When multiple classes implement the same interface, they can be treated as instances of that interface, allowing for flexible code that can work with different implementations.

Example of Polymorphism with Interfaces

class Animal {
void speak(); // Abstract method
}

class Dog implements Animal {
@override
void speak() {
print('Dog barks.');
}
}

class Cat implements Animal {
@override
void speak() {
print('Cat meows.');
}
}

void makeAnimalSpeak(Animal animal) {
animal.speak(); // Calls the speak method of the specific animal
}

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

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

In this example, both Dog and Cat implement the Animal interface. The makeAnimalSpeak function takes an Animal parameter and calls the speak method. This demonstrates polymorphism, as the function can accept any object that implements the Animal interface, allowing for different behaviors based on the actual object type.

3. Benefits of Polymorphism

  • Code Reusability: Polymorphism allows you to write generic code that can work with different types of objects, reducing code duplication.
  • Flexibility: You can easily extend your code by adding new classes that implement existing interfaces or override methods without modifying the existing code.
  • Maintainability: Polymorphic code is often easier to maintain and understand, as it promotes a clear structure and separation of concerns.

4. Conclusion

Polymorphism in Dart is a powerful feature that enhances the flexibility and reusability of your code. By using method overriding and interfaces, you can create a system where different classes can be treated uniformly while still providing their specific behaviors. Understanding how to implement polymorphism effectively is essential for building robust and maintainable Dart applications.