Dart this/super Keywords

Referencing current and parent class members

🔗 What are this/super?

The 'this' keyword refers to the current object instance, while 'super' refers to the parent class. They help distinguish between local and class variables and access parent class members.


class Person {
  String name;
  Person(this.name); // 'this' refers to current object
}

class Student extends Person {
  Student(String name) : super(name); // 'super' calls parent constructor
}
                                    

Key this/super Concepts

👆

this Keyword

Refers to current object instance

this.name = name;
⬆️

super Keyword

Refers to parent class

super.methodName();
🔧

Constructor Calls

Call parent constructors

: super(parameter)
🎯

Disambiguation

Resolve naming conflicts

this.value vs value

🔹 Using 'this' Keyword

The 'this' keyword helps distinguish between parameters and instance variables:

class Rectangle {
  double width;
  double height;
  
  // Constructor using 'this' to assign parameters to instance variables
  Rectangle(double width, double height) {
    this.width = width;   // 'this.width' refers to instance variable
    this.height = height; // 'height' parameter assigns to 'this.height'
  }
  
  // Shorter syntax using 'this' in constructor parameters
  // Rectangle(this.width, this.height);  // Alternative way
  
  // Method using 'this' to refer to current object
  void setDimensions(double width, double height) {
    this.width = width;   // Distinguish from parameter 'width'
    this.height = height; // Distinguish from parameter 'height'
  }
  
  double calculateArea() {
    return this.width * this.height; // 'this' is optional here
  }
  
  // Method that returns current object (method chaining)
  Rectangle scale(double factor) {
    this.width *= factor;
    this.height *= factor;
    return this; // Return current object for chaining
  }
  
  void displayInfo() {
    print('Rectangle: ${this.width} x ${this.height}');
    print('Area: ${this.calculateArea()}');
  }
}

void main() {
  Rectangle rect = Rectangle(5.0, 3.0);
  rect.displayInfo();
  
  // Method chaining using 'this'
  rect.scale(2.0).scale(1.5);
  print('After scaling:');
  rect.displayInfo();
  
  // Update dimensions
  rect.setDimensions(10.0, 8.0);
  print('After setting new dimensions:');
  rect.displayInfo();
}

Output:

Rectangle: 5.0 x 3.0

Area: 15.0

After scaling:

Rectangle: 15.0 x 9.0

Area: 135.0

After setting new dimensions:

Rectangle: 10.0 x 8.0

Area: 80.0

🔹 Using 'super' Keyword

The 'super' keyword accesses parent class members and constructors:

class Animal {
  String name;
  int age;
  
  Animal(this.name, this.age);
  
  void makeSound() {
    print('$name makes a sound');
  }
  
  void displayInfo() {
    print('Animal: $name, Age: $age');
  }
  
  void sleep() {
    print('$name is sleeping');
  }
}

class Dog extends Animal {
  String breed;
  
  // Constructor calling parent constructor with 'super'
  Dog(String name, int age, this.breed) : super(name, age);
  
  // Override parent method
  @override
  void makeSound() {
    print('$name barks: Woof! Woof!');
  }
  
  // Method that calls parent method using 'super'
  void makeAllSounds() {
    super.makeSound();  // Call parent's makeSound method
    this.makeSound();   // Call current class's makeSound method
  }
  
  // Override parent method but extend it
  @override
  void displayInfo() {
    super.displayInfo(); // Call parent's displayInfo first
    print('Breed: $breed');
  }
  
  // New method specific to Dog
  void fetch() {
    print('$name is fetching the ball');
  }
}

class Puppy extends Dog {
  bool isTraining;
  
  Puppy(String name, int age, String breed, this.isTraining) 
      : super(name, age, breed);
  
  @override
  void makeSound() {
    print('$name makes puppy sounds: Yip! Yip!');
  }
  
  @override
  void displayInfo() {
    super.displayInfo(); // Calls Dog's displayInfo (which calls Animal's)
    print('Training: ${isTraining ? "Yes" : "No"}');
  }
  
  void playWithToys() {
    print('$name is playing with toys');
    super.sleep(); // Call grandparent's sleep method
  }
}

void main() {
  Dog dog = Dog('Buddy', 3, 'Golden Retriever');
  
  print('=== Dog Information ===');
  dog.displayInfo();
  
  print('\n=== Dog Sounds ===');
  dog.makeAllSounds();
  
  print('\n=== Puppy Information ===');
  Puppy puppy = Puppy('Max', 1, 'Labrador', true);
  puppy.displayInfo();
  
  print('\n=== Puppy Activities ===');
  puppy.makeSound();
  puppy.playWithToys();
}

Output:

=== Dog Information ===

Animal: Buddy, Age: 3

Breed: Golden Retriever

=== Dog Sounds ===

Buddy makes a sound

Buddy barks: Woof! Woof!

=== Puppy Information ===

Animal: Max, Age: 1

Breed: Labrador

Training: Yes

=== Puppy Activities ===

Max makes puppy sounds: Yip! Yip!

Max is playing with toys

Max is sleeping

🔹 Constructor Chaining with super

Using 'super' to chain constructors in inheritance hierarchy:

class Vehicle {
  String brand;
  int year;
  double price;
  
  Vehicle(this.brand, this.year, this.price) {
    print('Vehicle constructor called: $brand');
  }
  
  void displayBasicInfo() {
    print('$brand ($year) - \$${price.toStringAsFixed(2)}');
  }
}

class Car extends Vehicle {
  int doors;
  String fuelType;
  
  // Constructor with super call
  Car(String brand, int year, double price, this.doors, this.fuelType) 
      : super(brand, year, price) {
    print('Car constructor called: $doors doors, $fuelType');
  }
  
  @override
  void displayBasicInfo() {
    super.displayBasicInfo(); // Call parent method
    print('Doors: $doors, Fuel: $fuelType');
  }
}

class ElectricCar extends Car {
  double batteryCapacity;
  int range;
  
  // Constructor chaining through multiple levels
  ElectricCar(String brand, int year, double price, int doors, 
              this.batteryCapacity, this.range) 
      : super(brand, year, price, doors, 'Electric') {
    print('ElectricCar constructor called: ${batteryCapacity}kWh battery');
  }
  
  @override
  void displayBasicInfo() {
    super.displayBasicInfo(); // Calls Car's displayBasicInfo
    print('Battery: ${batteryCapacity}kWh, Range: ${range}km');
  }
  
  void chargeBattery() {
    print('$brand is charging... Battery capacity: ${batteryCapacity}kWh');
  }
}

// Example with named constructors and super
class Motorcycle extends Vehicle {
  bool hasSidecar;
  
  // Regular constructor
  Motorcycle(String brand, int year, double price, this.hasSidecar) 
      : super(brand, year, price);
  
  // Named constructor
  Motorcycle.withSidecar(String brand, int year, double price) 
      : this(brand, year, price, true);
  
  // Named constructor calling super
  Motorcycle.vintage(String brand, int year) 
      : hasSidecar = false,
        super(brand, year, 15000.0);
  
  @override
  void displayBasicInfo() {
    super.displayBasicInfo();
    print('Sidecar: ${hasSidecar ? "Yes" : "No"}');
  }
}

void main() {
  print('=== Creating Electric Car ===');
  ElectricCar tesla = ElectricCar('Tesla', 2023, 45000.0, 4, 75.0, 400);
  
  print('\n=== Electric Car Info ===');
  tesla.displayBasicInfo();
  tesla.chargeBattery();
  
  print('\n=== Creating Vintage Motorcycle ===');
  Motorcycle vintage = Motorcycle.vintage('Harley Davidson', 1965);
  vintage.displayBasicInfo();
  
  print('\n=== Creating Motorcycle with Sidecar ===');
  Motorcycle sidecarBike = Motorcycle.withSidecar('BMW', 2020, 25000.0);
  sidecarBike.displayBasicInfo();
}

Output:

=== Creating Electric Car ===

Vehicle constructor called: Tesla

Car constructor called: 4 doors, Electric

ElectricCar constructor called: 75.0kWh battery

=== Electric Car Info ===

Tesla (2023) - $45000.00

Doors: 4, Fuel: Electric

Battery: 75.0kWh, Range: 400km

Tesla is charging... Battery capacity: 75.0kWh

=== Creating Vintage Motorcycle ===

Vehicle constructor called: Harley Davidson

Harley Davidson (1965) - $15000.00

Sidecar: No

=== Creating Motorcycle with Sidecar ===

Vehicle constructor called: BMW

BMW (2020) - $25000.00

Sidecar: Yes

🧠 Test Your Knowledge

What does the 'super' keyword refer to?