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

FeatureDescription
Cannot be instantiatedYou cannot create objects directly from abstract classes
Can have abstract methodsMethods declared without implementation
Can have concrete methodsRegular methods with full implementation
Must be extendedOther 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!