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