abstract class declares a type with abstract members that concrete classes must implement. A function that takes the abstract type works on any concrete implementer; that is polymorphic dispatch. Any class can be used as an interface with implements, which forces the implementer to re-declare every member.

Program

Play the program to dispatch a describe call through the abstract Shape type.

abstract_interface.dart
abstract class Shape {
  String get name;
  int area();
}

class Square implements Shape {
  final int side;
  Square(this.side);
  @override
  String get name => 'square';
  @override
  int area() => side * side;
}

void describe(Shape s) {
  print('${s.name} area=${s.area()}');
}

void main() {
  Shape s = Square(4);
  describe(s);
}
abstract class `abstract class Shape` declares a type that cannot be instantiated directly.
abstract member `String get name;` and `int area();` end with `;` and no body, so implementers must provide one.
polymorphic dispatch `describe(Shape s)` accepts any `Shape`; calling `s.name` and `s.area()` runs the concrete `Square` implementation.