Menu
Coddy logo textTech

Method Overriding

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 38 of 110.

Method overriding occurs when a child class provides its own implementation of a method that already exists in the parent class. This allows subclasses to customize inherited behavior while keeping the same method signature.

When you define a method in a child class with the same name and parameters as one in the parent, the child's version takes over:

class Animal {
  String name;
  
  Animal(this.name);
  
  void speak() {
    print('$name makes a sound');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name);
  
  void speak() {
    print('$name barks: Woof!');
  }
}

void main() {
  var animal = Animal('Generic');
  var dog = Dog('Buddy');
  
  animal.speak();  // Generic makes a sound
  dog.speak();     // Buddy barks: Woof!
}

When you call speak() on a Dog instance, Dart executes the Dog's version, not the Animal's. The child class has overridden the parent's method.

You can also combine overriding with super to extend rather than replace the parent's behavior:

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void speak() {
    super.speak();  // Call parent's version first
    print('$name also purrs');
  }
}

This pattern lets you build upon existing functionality. The key rule is simple: same method name and parameters in the child class replaces the parent's implementation when called on child instances.

challenge icon

Challenge

Easy

Let's build a notification system that demonstrates how child classes can override parent methods to customize behavior. You'll create different notification types that each deliver messages in their own unique way.

You'll organize your code into two files:

  • notification.dart: Define your notification hierarchy here:
    • A Notification class (the parent) with a String title and String message. Include a constructor that takes both values and a method send() that prints Notification: [title] - [message]
    • An EmailNotification class that extends Notification and adds a String recipient property. Override the send() method to print Sending email to [recipient]: [title] - [message]
    • A PushNotification class that extends Notification and adds a String deviceId property. Override the send() method to first call the parent's send() using super, then print Pushed to device: [deviceId] on the next line
  • main.dart: Import your notification file and demonstrate method overriding in action:
    • Create a base Notification with title 'Alert' and message 'System update available'
    • Call its send() method
    • Print an empty line
    • Create an EmailNotification with title 'Welcome', message 'Thanks for signing up!', and recipient 'user@example.com'
    • Call its send() method
    • Print an empty line
    • Create a PushNotification with title 'Reminder', message 'Meeting in 10 minutes', and deviceId 'DEVICE-001'
    • Call its send() method

Notice how EmailNotification completely replaces the parent's behavior, while PushNotification extends it by calling super.send() first. Both approaches are valid ways to override methods depending on your needs.

Expected output:

Notification: Alert - System update available

Sending email to user@example.com: Welcome - Thanks for signing up!

Notification: Reminder - Meeting in 10 minutes
Pushed to device: DEVICE-001

Cheat sheet

Method overriding occurs when a child class provides its own implementation of a method that already exists in the parent class. The child's version replaces the parent's when called on child instances.

To override a method, define it in the child class with the same name and parameters:

class Animal {
  String name;
  
  Animal(this.name);
  
  void speak() {
    print('$name makes a sound');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name);
  
  void speak() {
    print('$name barks: Woof!');
  }
}

void main() {
  var animal = Animal('Generic');
  var dog = Dog('Buddy');
  
  animal.speak();  // Generic makes a sound
  dog.speak();     // Buddy barks: Woof!
}

You can use super to call the parent's version and extend rather than replace behavior:

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void speak() {
    super.speak();  // Call parent's version first
    print('$name also purrs');
  }
}

Try it yourself

import 'notification.dart';

void main() {
  // TODO: Create a base Notification with title 'Alert' and message 'System update available'
  // Call its send() method

  // TODO: Print an empty line

  // TODO: Create an EmailNotification with:
  // - title: 'Welcome'
  // - message: 'Thanks for signing up!'
  // - recipient: 'user@example.com'
  // Call its send() method

  // TODO: Print an empty line

  // TODO: Create a PushNotification with:
  // - title: 'Reminder'
  // - message: 'Meeting in 10 minutes'
  // - deviceId: 'DEVICE-001'
  // Call its send() method
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming