Skip to main content
Super parameters are a syntactic sugar in Dart constructors that allow a subclass to forward parameters directly to the superclass constructor. This syntax eliminates the need to manually pass arguments into the super() invocation, implicitly binding the subclass parameter to the corresponding parameter in the superclass.

Syntax and Mechanics

The syntax uses the super keyword followed by the parameter name (e.g., super.parameterName) within the subclass constructor’s formal parameter list. When a super parameter is used, the associated argument is implicitly added to the superclass constructor call. The type of the parameter is inferred from the superclass constructor, though it may be explicitly annotated.

Comparison

Verbose Syntax (Standard Initializer):
class Vector2d {
  final double x;
  final double y;
  Vector2d(this.x, this.y);
}

class Vector3d extends Vector2d {
  final double z;

  // Manually passing x and y to super
  Vector3d(double x, double y, this.z) : super(x, y);
}
Super Parameter Syntax:
class Vector3d extends Vector2d {
  final double z;

  // Forwarding x and y implicitly
  Vector3d(super.x, super.y, this.z);
}

Positional Super Parameters

For positional parameters, the order of the super parameters in the subclass determines which positional parameters they map to in the superclass constructor. They are matched sequentially.
class Base {
  Base(int first, String second);
}

class Derived extends Base {
  // 'super.first' maps to Base's 'first' (int)
  // 'super.second' maps to Base's 'second' (String)
  Derived(super.first, super.second);
}

Named Super Parameters

For named parameters, the mapping is based on the parameter name. The subclass parameter name must match the name defined in the superclass constructor.
class Config {
  Config({required bool debugMode, int timeout = 1000});
}

class AppConfig extends Config {
  final String appName;

  // 'super.debugMode' maps to Config({debugMode})
  // 'super.timeout' maps to Config({timeout})
  AppConfig({
    required this.appName,
    required super.debugMode,
    super.timeout,
  });
}

Type Inference and Annotations

The type of a super parameter is inferred from the corresponding parameter in the super constructor. Explicit type annotations are permitted but generally redundant unless narrowing the type is required.
class Parent {
  Parent(num value);
}

class Child extends Parent {
  // Infers type 'num' from Parent
  Child(super.value); 
  
  // Explicitly typing as 'int' (valid if int is a subtype of num)
  Child.explicit(int super.value); 
}

Mixing Parameters

Super parameters can be mixed with initializing formals (this.prop) and standard function parameters within the same constructor signature.
class Employee extends Person {
  final String role;

  Employee(
    super.name,        // Super parameter (Positional)
    this.role,         // Initializing formal
    {super.age}        // Super parameter (Named)
  );
}

Constraints

  1. Exclusive Initialization: If a constructor utilizes any super parameters (positional or named), it is a compile-time error to include an explicit super() invocation in the initializer list. The compiler constructs the super call implicitly.
  2. Name Matching: Named super parameters rely strictly on identifier equality; you cannot rename a parameter while forwarding it via super.name.
  3. Variable Scope: Super parameters are available within the constructor body as local variables. However, they are not bound to this and do not become instance fields of the subclass.
Master Dart with Deep Grasping Methodology!Learn More