Dart Abstract Classes
Creating blueprints for other classes
🎯 What are Abstract Classes?
Abstract classes in Dart are blueprints that cannot be instantiated directly. They define common structure and behavior for subclasses, ensuring consistent implementation across related classes.
// Abstract class - cannot create objects directly
abstract class Animal {
void makeSound(); // Abstract method
void sleep() => print('Sleeping...'); // Concrete method
}
Key Abstract Class Concepts
Cannot Instantiate
Abstract classes cannot create objects
// Animal animal = Animal(); // Error!
Abstract Methods
Methods without implementation
void makeSound(); // Must be implemented
Concrete Methods
Methods with implementation
void sleep() => print('Sleeping...');
Inheritance
Subclasses must implement abstract methods
class Dog extends Animal {
void makeSound() => print('Woof!');
}
🔹 Basic Abstract Class Example
Here's a simple abstract class with both abstract and concrete methods:
abstract class Shape {
// Abstract method - must be implemented by subclasses
double calculateArea();
// Concrete method - can be used by all subclasses
void displayInfo() {
print('This is a shape with area: ${calculateArea()}');
}
}
class Circle extends Shape {
double radius;
Circle(this.radius);
@override
double calculateArea() {
return 3.14159 * radius * radius;
}
}
class Rectangle extends Shape {
double width, height;
Rectangle(this.width, this.height);
@override
double calculateArea() {
return width * height;
}
}
void main() {
Circle circle = Circle(5);
Rectangle rectangle = Rectangle(4, 6);
circle.displayInfo(); // This is a shape with area: 78.53975
rectangle.displayInfo(); // This is a shape with area: 24.0
}
Output:
This is a shape with area: 78.53975
This is a shape with area: 24.0
🔹 Abstract Class with Constructor
Abstract classes can have constructors for initialization:
abstract class Vehicle {
String brand;
int year;
// Constructor in abstract class
Vehicle(this.brand, this.year);
// Abstract method
void startEngine();
// Concrete method
void displayDetails() {
print('$brand ($year)');
}
}
class Car extends Vehicle {
Car(String brand, int year) : super(brand, year);
@override
void startEngine() {
print('Car engine started with key');
}
}
class Motorcycle extends Vehicle {
Motorcycle(String brand, int year) : super(brand, year);
@override
void startEngine() {
print('Motorcycle engine started with button');
}
}
void main() {
Car car = Car('Toyota', 2023);
Motorcycle bike = Motorcycle('Honda', 2022);
car.displayDetails(); // Toyota (2023)
car.startEngine(); // Car engine started with key
bike.displayDetails(); // Honda (2022)
bike.startEngine(); // Motorcycle engine started with button
}
Output:
Toyota (2023)
Car engine started with key
Honda (2022)
Motorcycle engine started with button
🔹 Multiple Abstract Methods
Abstract classes can have multiple abstract methods:
abstract class Employee {
String name;
Employee(this.name);
// Multiple abstract methods
double calculateSalary();
String getJobTitle();
void performWork();
// Concrete method
void introduce() {
print('Hi, I am $name, a ${getJobTitle()}');
}
}
class Developer extends Employee {
double hourlyRate;
int hoursWorked;
Developer(String name, this.hourlyRate, this.hoursWorked) : super(name);
@override
double calculateSalary() => hourlyRate * hoursWorked;
@override
String getJobTitle() => 'Software Developer';
@override
void performWork() => print('Writing code...');
}
void main() {
Developer dev = Developer('Alice', 50.0, 40);
dev.introduce(); // Hi, I am Alice, a Software Developer
dev.performWork(); // Writing code...
print('Salary: \$${dev.calculateSalary()}'); // Salary: $2000.0
}
Output:
Hi, I am Alice, a Software Developer
Writing code...
Salary: $2000.0