What are Abstract Classes?
An abstract class is a class that cannot be instantiated directly. It is designed to be a blueprint for other classes. Abstract classes may contain both abstract methods (methods without a body) and concrete methods (with implementation). They are declared using the abstract keyword. Abstract classes are essential for defining common behavior that subclasses can share while enforcing that certain methods are implemented by the subclasses.
Defining an Abstract Class
To declare an abstract class, add the abstract keyword before the class keyword. Abstract classes can have constructors, fields, and both abstract and concrete methods.
Abstract Methods
An abstract method is a method declared without an implementation. It must be overridden by any non‑abstract subclass. Abstract methods can only exist inside abstract classes. They define a contract that subclasses must fulfill.
Constructors in Abstract Classes
Even though you cannot instantiate an abstract class, it can still have constructors. These constructors are called when a concrete subclass is instantiated. They are useful for initializing fields defined in the abstract class.
Abstract Classes vs Interfaces
In Dart, every class defines an interface, so the line between abstract classes and interfaces can be blurry. However, there are important differences:
- An abstract class can have fields and concrete methods; an interface (via
implements) cannot provide any implementation.
- An abstract class can have fields and concrete methods; an interface (via
- A class can implement multiple interfaces but can extend only one abstract class.
- Use an abstract class when you want to share code among several closely related classes. Use interfaces (implicit or explicit) when you want to define a capability that can be implemented by unrelated classes.
Factory Constructors in Abstract Classes
Abstract classes can have factory constructors. This is useful when you want to return an instance of a concrete subclass based on some input, while keeping the abstract class as the only visible type.
Abstract Classes and Polymorphism
Abstract classes are often used as base types for polymorphism. You can write functions that accept the abstract type, and at runtime they work with any concrete subclass.
Common Mistakes
- Trying to instantiate an abstract class: This results in a compile error.
- Forgetting to override an abstract method: The subclass must override all abstract methods; otherwise, it must also be declared
abstract.
- Forgetting to override an abstract method: The subclass must override all abstract methods; otherwise, it must also be declared
- Using
implementswhen you meantextends: If you want to reuse implementation, useextends; if you only want to satisfy a contract, useimplements.
- Using
Best Practices
- Use abstract classes to define a common base with shared fields and methods.
- Keep abstract classes focused – they should represent a clear concept (e.g.,
Animal,Shape,PaymentProcessor).
- Keep abstract classes focused – they should represent a clear concept (e.g.,
- Prefer composition over inheritance when appropriate, but abstract classes are a good choice for true 'is‑a' relationships.
- Document abstract methods clearly so implementers know what behavior is expected.
Complete Example
Key Takeaways
- Abstract classes (declared with
abstract) cannot be instantiated.
- Abstract classes (declared with
- They may contain both abstract methods (no body) and concrete methods (with implementation).
- Subclasses must override all abstract methods, or they must also be abstract.
- Abstract classes can have constructors, fields, and factory constructors.
- Use abstract classes when you have a base type with shared implementation and you want to enforce that certain methods are implemented by subclasses.