Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A final class in Dart is a class modifier that completely restricts subtyping outside of its declaring library. It guarantees that the class hierarchy is closed to external modification, preventing external code from either extending or implementing the class, while still permitting unrestricted instantiation.

Core Mechanics

  • Instantiation: A final class can be instantiated from any library.
  • Extension (extends): Prohibited outside the declaring library. Allowed within the declaring library.
  • Implementation (implements): Prohibited outside the declaring library. Allowed within the declaring library.
  • Mixin Application (with): Prohibited outside the declaring library.

Syntax and Library Boundaries

The behavior of a final class strictly depends on the library boundary (typically the file boundary, unless part directives are used). File 1: core_library.dart (Declaring Library)
// Declaration of a final class
final class NetworkRequest {
  void send() => print('Sending request...');
}

// VALID: Subtyping is allowed within the same library.
// Note: Subclasses must propagate the restriction (see rules below).
final class GetRequest extends NetworkRequest {}
base class PostRequest implements NetworkRequest {
  @override
  void send() => print('Sending POST...');
}
File 2: external_module.dart (External Library)
import 'core_library.dart';

void main() {
  // VALID: Instantiation is allowed anywhere.
  NetworkRequest req = NetworkRequest();
  req.send();
}

// ERROR: Cannot extend a final class outside its library.
class PutRequest extends NetworkRequest {} 

// ERROR: Cannot implement a final class outside its library.
class MockRequest implements NetworkRequest {
  @override
  void send() {}
}

Modifier Propagation Rules

Dart enforces strict modifier propagation to prevent external code from bypassing the final restriction via a subclass. If a class extends or implements a final class within the same library, that subclass must be explicitly marked with one of the following modifiers:
  1. final: Completely closes the subclass to external subtyping.
  2. base: Allows external extension, but prohibits external implementation.
  3. sealed: Creates an abstract, exhaustively switchable subclass that also restricts external subtyping.
final class Parent {}

// VALID
final class ChildA extends Parent {}
base class ChildB extends Parent {}
sealed class ChildC extends Parent {}

// ERROR: The subclass must be marked base, final, or sealed.
class ChildD extends Parent {} 

Interaction with Other Modifiers

  • abstract final class: The class cannot be instantiated anywhere, and cannot be subtyped outside its own library. It acts purely as an internal base class or interface.
  • interface vs base vs final:
    • interface blocks external extends.
    • base blocks external implements.
    • final blocks both external extends and implements.
Master Dart with Deep Grasping Methodology!Learn More