Answer
Overview
Yes, Flutter/Dart fully supports polymorphism! Polymorphism is one of the four pillars of Object-Oriented Programming (OOP). It allows objects of different classes to be treated as objects of a common parent class, enabling flexible and extensible code.
What is Polymorphism?
Polymorphism = "Many forms"
It means the same method or property can behave differently depending on the object that invokes it.
Types of Polymorphism
1. Compile-Time Polymorphism (Method Overloading)
Dart does NOT support method overloading (same method name with different parameters). Instead, use optional/named parameters.
dart// ❌ Not supported in Dart class Calculator { int add(int a, int b) => a + b; double add(double a, double b) => a + b; // Error: duplicate method } // ✅ Use optional/named parameters instead class Calculator { num add(num a, num b) => a + b; }
2. Runtime Polymorphism (Method Overriding)
Method overriding allows a subclass to provide a specific implementation of a method defined in its parent class.
dartclass Animal { void speak() { print('Animal makes a sound'); } } class Dog extends Animal { void speak() { print('Dog barks: Woof!'); } } class Cat extends Animal { void speak() { print('Cat meows: Meow!'); } } void main() { Animal animal1 = Dog(); Animal animal2 = Cat(); animal1.speak(); // Output: Dog barks: Woof! animal2.speak(); // Output: Cat meows: Meow! }
Key Point: The method called depends on the actual object type at runtime, not the reference type.
Polymorphism with Abstract Classes
Abstract classes define a contract that subclasses must implement.
dartabstract class Shape { double area(); // Abstract method } class Circle extends Shape { final double radius; Circle(this.radius); double area() => 3.14159 * radius * radius; } class Rectangle extends Shape { final double width; final double height; Rectangle(this.width, this.height); double area() => width * height; } void printArea(Shape shape) { print('Area: ${shape.area()}'); } void main() { printArea(Circle(5)); // Area: 78.53975 printArea(Rectangle(4, 6)); // Area: 24.0 }
Polymorphism with Interfaces
In Dart, every class is an implicit interface. You can implement multiple interfaces using
implementsdartabstract class Flyable { void fly(); } abstract class Swimmable { void swim(); } class Duck implements Flyable, Swimmable { void fly() => print('Duck is flying'); void swim() => print('Duck is swimming'); } class Airplane implements Flyable { void fly() => print('Airplane is flying'); } void makeFly(Flyable flyable) { flyable.fly(); } void main() { makeFly(Duck()); // Duck is flying makeFly(Airplane()); // Airplane is flying }
Polymorphism in Flutter Widgets
Flutter extensively uses polymorphism through the
Widgetdartclass MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Column( children: [ // All are Widget types (polymorphic) Text('Hello'), // StatelessWidget Icon(Icons.star), // StatelessWidget Image.asset('logo.png'), // StatefulWidget Container(), // StatelessWidget ], ), ), ); } }
Behind the scenes:
- ,text
Text,textIcon,textImageare all subclasses oftextContainertextWidget - acceptstext
Column(polymorphism at work)textList<Widget>
Polymorphism with Payment Example
dartabstract class PaymentGateway { Future<bool> processPayment(double amount); } class RazorpayGateway implements PaymentGateway { Future<bool> processPayment(double amount) async { print('Processing ₹$amount via Razorpay'); await Future.delayed(Duration(seconds: 2)); return true; } } class StripeGateway implements PaymentGateway { Future<bool> processPayment(double amount) async { print('Processing \$$amount via Stripe'); await Future.delayed(Duration(seconds: 2)); return true; } } class PaymentService { final PaymentGateway gateway; PaymentService(this.gateway); Future<void> pay(double amount) async { final success = await gateway.processPayment(amount); if (success) { print('Payment successful!'); } } } void main() async { // Same service, different gateways (polymorphism) final razorpay = PaymentService(RazorpayGateway()); await razorpay.pay(500); final stripe = PaymentService(StripeGateway()); await stripe.pay(100); }
Operator Overloading (Special Polymorphism)
Dart allows operator overloading for custom classes.
dartclass Vector { final double x, y; Vector(this.x, this.y); // Overload + operator Vector operator +(Vector other) { return Vector(x + other.x, y + other.y); } // Overload * operator Vector operator *(double scalar) { return Vector(x * scalar, y * scalar); } String toString() => 'Vector($x, $y)'; } void main() { final v1 = Vector(1, 2); final v2 = Vector(3, 4); print(v1 + v2); // Vector(4.0, 6.0) print(v1 * 2); // Vector(2.0, 4.0) }
Polymorphism Summary Table
| Type | Dart Support | Example |
|---|---|---|
| Method Overloading | ❌ Not directly | Use optional parameters |
| Method Overriding | ✅ Yes | text |
| Abstract Classes | ✅ Yes | text |
| Interfaces | ✅ Yes | text |
| Operator Overloading | ✅ Yes | text text |
Benefits of Polymorphism
| Benefit | Description |
|---|---|
| Code Reusability | Write generic code that works with multiple types |
| Flexibility | Easy to add new classes without changing existing code |
| Maintainability | Changes in subclasses don't affect parent class |
| Extensibility | Add new behaviors by extending classes |
| Testability | Mock implementations for testing |
Real-World Flutter Example
dart// Base class abstract class DataSource { Future<List<String>> fetchData(); } // Remote implementation class RemoteDataSource implements DataSource { Future<List<String>> fetchData() async { // Fetch from API await Future.delayed(Duration(seconds: 2)); return ['Data from API']; } } // Local implementation class LocalDataSource implements DataSource { Future<List<String>> fetchData() async { // Fetch from local DB return ['Data from DB']; } } // Mock implementation (for testing) class MockDataSource implements DataSource { Future<List<String>> fetchData() async { return ['Mock Data']; } } // Repository uses polymorphism class UserRepository { final DataSource dataSource; UserRepository(this.dataSource); Future<void> loadUsers() async { final data = await dataSource.fetchData(); print('Loaded: $data'); } } void main() async { // Same repository, different data sources final remoteRepo = UserRepository(RemoteDataSource()); await remoteRepo.loadUsers(); // Loads from API final localRepo = UserRepository(LocalDataSource()); await localRepo.loadUsers(); // Loads from DB final mockRepo = UserRepository(MockDataSource()); await mockRepo.loadUsers(); // Loads mock data (for testing) }
Summary
Yes, Dart supports polymorphism! Use method overriding with
, abstract classes, interfaces withtext@override, and operator overloading. Polymorphism enables flexible, maintainable, and testable code in Flutter apps.textimplements
Learn more at Dart OOP Guide and Flutter Widget Catalog.