Abstract Classes
Abstract classes in Dart are like blueprints or templates that define a structure for other classes to follow. Think of them as incomplete classes that cannot be instantiated directly - they're meant to be extended by other classes.
What are Abstract Classes?
An abstract class is a class that contains one or more abstract methods (methods without implementation) or serves as a base class that shouldn't be instantiated directly. It's like having a recipe template where some steps are defined, but others need to be filled in by whoever uses the template.
Creating Abstract Classes
You create an abstract class using the abstract keyword:
abstract class Animal {
String name;
Animal(this.name);
// Abstract method - no implementation
void makeSound();
// Concrete method - has implementation
void sleep() {
print('$name is sleeping...');
}
}
Key Characteristics
| Feature | Description |
|---|---|
| Cannot be instantiated | You cannot create objects directly from abstract classes |
| Can have abstract methods | Methods declared without implementation |
| Can have concrete methods | Regular methods with full implementation |
| Must be extended | Other classes must extend them to be useful |
Implementing Abstract Classes
When a class extends an abstract class, it must implement all abstract methods:
class Dog extends Animal {
Dog(String name) : super(name);
@override
void makeSound() {
print('$name barks: Woof! Woof!');
}
}
class Cat extends Animal {
Cat(String name) : super(name);
@override
void makeSound() {
print('$name meows: Meow! Meow!');
}
}
Using Abstract Classes
void main() {
// This would cause an error:
// Animal animal = Animal('Generic'); // Cannot instantiate abstract class
// This works fine:
Dog myDog = Dog('Buddy');
Cat myCat = Cat('Whiskers');
myDog.makeSound(); // Output: Buddy barks: Woof! Woof!
myCat.makeSound(); // Output: Whiskers meows: Meow! Meow!
myDog.sleep(); // Output: Buddy is sleeping...
myCat.sleep(); // Output: Whiskers is sleeping...
}
When to Use Abstract Classes
Abstract classes are perfect when you want to:
- Share code among several closely related classes
- Enforce a contract that subclasses must follow
- Provide default implementations for some methods while requiring others to be implemented
- Create a common interface with shared functionality
Abstract Classes vs Interfaces
While Dart doesn't have explicit interfaces like some languages, abstract classes can serve a similar purpose:
abstract class Drawable {
void draw();
void resize(double factor);
}
abstract class Clickable {
void onClick();
}
// A class can implement multiple abstract classes
class Button implements Drawable, Clickable {
@override
void draw() {
print('Drawing button');
}
@override
void resize(double factor) {
print('Resizing button by $factor');
}
@override
void onClick() {
print('Button clicked!');
}
}
Abstract classes are powerful tools for creating well-structured, maintainable code. They help you define clear contracts while allowing for code reuse and polymorphism!