class Animal
{
void makeSound()
{
print('Generic animal sound');
}
}
class Dog extends Animal
{
@override void makeSound()
{
print('Woof!');
}
}
class Cat extends Animal
{
@override
void makeSound()
{
print('Meow!');
}
}
void main()
{
List<Animal> animals = [Dog(), Cat()];
for (Animal animal in animals)
{
animal.makeSound();
}
}
- In this example:
- We have a list of `Animal` objects, but it contains both `Dog` and `Cat` objects.
- When we call `animal.makeSound()` in the loop, the correct `makeSound()` method for each object is invoked.
2. **Method Overloading:**
- A class can have multiple methods with the same name but different parameters.
class Animal
{
void makeSound()
{
print('Generic animal sound');
}
}
class Dog extends Animal
{
@override void makeSound()
{
print('Woof!');
}
}
class Cat extends Animal
{
@override
void makeSound()
{
print('Meow!');
}
}
void main()
{
List<Animal> animals = [Dog(), Cat()];
for (Animal animal in animals)
{
animal.makeSound();
}
}
In this example:
The Calculator class has two add methods, one for integers and one for doubles.
The Dart compiler determines which add method to call based on the types of arguments provided.
What is Polymorphism?
Polymorphism is another fundamental concept in Object-Oriented Programming (OOP).
It literally means "many forms."
In essence, it allows objects of different classes to be treated as objects of a common type.
Types of Polymorphism in Dart:
Method Overriding:
We've already touched upon this: Subclasses can override methods inherited from their superclass.
This allows objects of different classes to behave differently when the same method is called on them.
Benefits of Polymorphism
Flexibility: Enables you to write more flexible and reusable code.
Code Maintainability: Makes it easier to modify or extend the behavior of objects without affecting other parts of the code.
Improved Design: Promotes loose coupling between classes, leading to more modular and maintainable systems.
In Summary
Polymorphism is a powerful concept that allows you to write more adaptable and maintainable code in Dart. By utilizing method overriding and method overloading, you can achieve a higher level of abstraction and flexibility in your object-oriented designs.
A program with a parent class and child classes that override the parent method.
class Animal {
void sound() {
print("Some generic animal sound");
}
}
class Dog extends Animal {
@override
void sound() {
print("Dog barks");
}
}
class Cat extends Animal {
@override
void sound() {
print("Cat meows");
}
}
void main() {
Animal myDog = Dog();
Animal myCat = Cat();
myDog.sound(); // Output: Dog barks
myCat.sound(); // Output: Cat meows
}
A program using an abstract class where different subclasses implement abstract methods differently.
abstract class Vehicle {
void start();
}
class Car extends Vehicle {
@override
void start() {
print("Car starts with a key.");
}
}
class Bike extends Vehicle {
@override
void start() {
print("Bike starts with a button.");
}
}
void main() {
Vehicle myCar = Car();
Vehicle myBike = Bike();
myCar.start(); // Output: Car starts with a key.
myBike.start(); // Output: Bike starts with a button.
}
A program using an interface to create different types of classes that implement the same method.
class Printable {
void printDetails();
}
class Document implements Printable {
@override
void printDetails() {
print("Printing document...");
}
}
class Photo implements Printable {
@override
void printDetails() {
print("Printing photo...");
}
}
void main() {
Printable doc = Document();
Printable pic = Photo();
doc.printDetails(); // Output: Printing document...
pic.printDetails(); // Output: Printing photo...
}
A program demonstrating polymorphism by storing different objects in a list of the parent type.
abstract class Shape {
void draw();
}
class Circle extends Shape {
@override
void draw() {
print("Drawing Circle");
}
}
class Square extends Shape {
@override
void draw() {
print("Drawing Square");
}
}
void main() {
List<Shape> shapes = [Circle(), Square()];
for (var shape in shapes) {
shape.draw();
}
}
Different payment methods using polymorphism.
abstract class PaymentMethod {
void processPayment(double amount);
}
class CreditCardPayment extends PaymentMethod {
@override
void processPayment(double amount) {
print("Processing credit card payment of \$${amount}");
}
}
class PaypalPayment extends PaymentMethod {
@override
void processPayment(double amount) {
print("Processing PayPal payment of \$${amount}");
}
}
void main() {
PaymentMethod payment = CreditCardPayment();
payment.processPayment(100.0);
payment = PaypalPayment();
payment.processPayment(50.0);
}
A program demonstrating operator overloading for polymorphism.
class Box {
double width;
double height;
Box(this.width, this.height);
Box operator +(Box other) {
return Box(width + other.width, height + other.height);
}
}
void main() {
Box box1 = Box(4.0, 5.0);
Box box2 = Box(2.0, 3.0);
Box box3 = box1 + box2;
print("Box 3 dimensions: ${box3.width} x ${box3.height}");
}
A program demonstrating polymorphism by overriding a getter.
class Product {
double get price => 100.0;
}
class DiscountedProduct extends Product {
@override
double get price => 80.0;
}
void main() {
Product product = Product();
Product discountedProduct = DiscountedProduct();
print("Original Price: ${product.price}");
print("Discounted Price: ${discountedProduct.price}");
}
Using polymorphism with a factory method to return different instances based on conditions.
abstract class Notification {
void send();
}
class EmailNotification extends Notification {
@override
void send() {
print("Sending Email Notification...");
}
}
class SMSNotification extends Notification {
@override
void send() {
print("Sending SMS Notification...");
}
}
Notification getNotification(String type) {
if (type == 'email') {
return EmailNotification();
} else {
return SMSNotification();
}
}
void main() {
Notification notification = getNotification("email");
notification.send();
}
A program demonstrating polymorphism with multiple classes implementing the same interface.
class Animal {
void makeSound() {}
}
class Lion extends Animal {
@override
void makeSound() {
print("Lion roars");
}
}
class Cow extends Animal {
@override
void makeSound() {
print("Cow moos");
}
}
void main() {
Animal lion = Lion();
Animal cow = Cow();
lion.makeSound();
cow.makeSound();
}
A program demonstrating polymorphism by using a generic method to perform different actions on different types of objects.
class Printer {
void printDetails(Object obj) {
print("Printing details of ${obj.runtimeType}");
}
}
class Car {
String brand;
Car(this.brand);
}
class Book {
String title;
Book(this.title);
}
void main() {
Printer printer = Printer();
printer.printDetails(Car("Tesla"));
printer.printDetails(Book("Dart Programming"));
}