Menu
Coddy logo textTech

Abstract Classes

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 43 of 110.

An abstract class is a class that cannot be instantiated directly. It serves as a blueprint for other classes, defining a common structure that subclasses must follow. You create one using the abstract keyword.

abstract class Shape {
  String color;
  
  Shape(this.color);
  
  void describe() {
    print('A $color shape');
  }
}

class Circle extends Shape {
  double radius;
  
  Circle(String color, this.radius) : super(color);
}

void main() {
  // Shape s = Shape('red');  // Error! Cannot instantiate abstract class
  var circle = Circle('blue', 5.0);
  circle.describe();  // A blue shape
}

Abstract classes are useful when you have a concept that's too general to exist on its own. A "Shape" is an idea, but you can't draw a shape without knowing if it's a circle, rectangle, or triangle. The abstract class defines what all shapes have in common, while concrete subclasses provide the specific details.

Notice that abstract classes can still have regular methods with implementations (like describe()) and constructors. Subclasses inherit these just like with normal inheritance. The key difference is simply that you cannot create an instance of the abstract class itself - you must use a concrete subclass.

challenge icon

Challenge

Easy

Let's build a vehicle system that demonstrates how abstract classes serve as blueprints for more specific types. You'll create an abstract base class that defines what all vehicles have in common, then extend it with concrete vehicle types.

You'll organize your code into two files:

  • vehicle.dart: Define your vehicle hierarchy here:
    • An abstract class Vehicle with a String brand and int year property. Include a constructor that takes both values and a method displayInfo() that prints [brand] ([year])
    • A Car class that extends Vehicle and adds an int doors property. Include a method honk() that prints Beep beep!
    • A Motorcycle class that extends Vehicle and adds a bool hasSidecar property. Include a method revEngine() that prints Vroom!
  • main.dart: Import your vehicle file and demonstrate how abstract classes work:
    • Create a Car with brand 'Toyota', year 2022, and doors 4
    • Call its displayInfo() method (inherited from Vehicle)
    • Print Doors: [doors]
    • Call its honk() method
    • Print an empty line
    • Create a Motorcycle with brand 'Harley', year 2021, and hasSidecar false
    • Call its displayInfo() method
    • Print Has sidecar: [hasSidecar]
    • Call its revEngine() method

Remember that you cannot create an instance of Vehicle directly since it's abstract - you must use one of the concrete subclasses. Both Car and Motorcycle inherit the displayInfo() method from the abstract parent class.

Expected output:

Toyota (2022)
Doors: 4
Beep beep!

Harley (2021)
Has sidecar: false
Vroom!

Cheat sheet

An abstract class is a class that cannot be instantiated directly. It serves as a blueprint for other classes, defining a common structure that subclasses must follow. Create one using the abstract keyword:

abstract class Shape {
  String color;
  
  Shape(this.color);
  
  void describe() {
    print('A $color shape');
  }
}

class Circle extends Shape {
  double radius;
  
  Circle(String color, this.radius) : super(color);
}

void main() {
  // Shape s = Shape('red');  // Error! Cannot instantiate abstract class
  var circle = Circle('blue', 5.0);
  circle.describe();  // A blue shape
}

Abstract classes can have:

  • Regular methods with implementations
  • Constructors
  • Properties

Subclasses inherit these members just like with normal inheritance. The key difference is that you cannot create an instance of the abstract class itself - you must use a concrete subclass.

Try it yourself

import 'vehicle.dart';

void main() {
  // TODO: Create a Car with brand 'Toyota', year 2022, and doors 4
  
  // TODO: Call displayInfo() on the car
  
  // TODO: Print "Doors: [doors]"
  
  // TODO: Call honk() on the car
  
  // TODO: Print an empty line
  
  // TODO: Create a Motorcycle with brand 'Harley', year 2021, and hasSidecar false
  
  // TODO: Call displayInfo() on the motorcycle
  
  // TODO: Print "Has sidecar: [hasSidecar]"
  
  // TODO: Call revEngine() on the motorcycle
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming