Answer
Overview
Polymorphism in Dart means "many forms" — an object can be treated as an instance of its parent type while behaving differently based on its actual type. It allows one interface to represent multiple implementations.
Types of Polymorphism
1. Runtime Polymorphism (Method Overriding)
dartabstract class Animal { String name; Animal(this.name); void makeSound(); // Abstract — must be overridden } class Dog extends Animal { Dog(String name) : super(name); void makeSound() => print('$name says: Woof!'); } class Cat extends Animal { Cat(String name) : super(name); void makeSound() => print('$name says: Meow!'); } class Duck extends Animal { Duck(String name) : super(name); void makeSound() => print('$name says: Quack!'); } void main() { // Polymorphic list — all Animal, different behaviors List<Animal> animals = [Dog('Buddy'), Cat('Whiskers'), Duck('Donald')]; for (final animal in animals) { animal.makeSound(); // Same call, different behavior } // Buddy says: Woof! // Whiskers says: Meow! // Donald says: Quack! }
2. Interface Polymorphism (implements)
dartabstract class Drawable { void draw(); } abstract class Resizable { void resize(double factor); } class Circle implements Drawable, Resizable { double radius; Circle(this.radius); void draw() => print('Drawing circle with radius $radius'); void resize(double f) => radius *= f; } void renderAll(List<Drawable> items) { for (final item in items) item.draw(); // Polymorphic call }
Polymorphism in Flutter
dartabstract class PaymentGateway { Future<bool> processPayment(double amount); } class StripeGateway implements PaymentGateway { Future<bool> processPayment(double amount) async { print('Processing \$$amount via Stripe'); return true; } } class RazorpayGateway implements PaymentGateway { Future<bool> processPayment(double amount) async { print('Processing ₹$amount via Razorpay'); return true; } } // Single function handles both — polymorphism Future<void> checkout(PaymentGateway gateway, double amount) async { await gateway.processPayment(amount); } void main() async { await checkout(StripeGateway(), 99.99); // Works await checkout(RazorpayGateway(), 1499.0); // Works }
Key Benefit: Polymorphism enables writing code that works with a supertype but responds differently based on the actual subtype — making code extensible without modification (Open/Closed Principle).