Home > Software engineering >  How to define value in the constructor to pass to the super constructor in Dart?
How to define value in the constructor to pass to the super constructor in Dart?

Time:07-25

I have some code like:

class P extends StatelessWidget {
  final List<int> l;
  final int x;

  const P({
    required this.l,
    required this.x,
    Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }

}

class A extends P {
  A({required int x, Key? key}) : super(l: [], x: x, key: key);
}

and what I would like to do is changing A class constructor in something like:

A({required int x, Key? key}) {
  final int a = 3;
  final int b = 5;
  final int c = -1;
}: super(l: [a, b, c], x: x, key: key);

is there a way to achieve something like that with Dart?

UPDATE

The version suggested by Yeasin works for the simple case from my example, but it fails if the case is more complicated like:

class A extends P {
  A({
    required int x,
    Key? key,
    ChangeNotifierProvider<UIComponentState> a = ChangeNotifierProvider<UIComponentState>((ref) => UIComponentState()),
    ChangeNotifierProvider<UIComponentState> b = ChangeNotifierProvider<UIComponentState>((ref) => UIComponentState()),
    ChangeNotifierProvider<UIComponentState> c = ChangeNotifierProvider<UIComponentState>((ref) => UIComponentState()),
  }) : super(l: [a, b, c], l2: [a, b, c], x: x, key: key);
}

as I get the error:

The default value of an optional parameter must be constant.

CodePudding user response:

Unless you plan on using a, b, and c later, adding variables for them is not very useful, especially when they're constants. You therefore could just use

super(l: [3, 5, -1], x: x, key: key)

directly, or if you really want to label the values, you could add named constants or static variables.

More generally, if you want variables to store intermediate computations, then you probably would be better off using a factory constructor (or static method) to create instances of your class:

class A extends P {
  A._({required List<int> l, required int x, required Key? key})
    : super(l: l, x: x, key: key);

  factory A({required int x, Key? key}) {
    var a = 3;
    var b = 5;
    var c = -1;
    return A._(l: [3, 5, -1], x: x, key: key);
  }
}

although note that doing that would make your class harder to derive from if you to use it as a base class later.

CodePudding user response:

You can do something like this

class A extends P {
  A({
    required int x,
    Key? key,
    int a = -1,
    int b = 5,
    int c = -1,
  }) : super(l: [a, b, c], x: x, key: key);
}

or try

class A extends P {
  A({
    required int x,
    Key? key,
    final int? a,
    final int? b,
    final int? c,
  }) : super(l: [a ?? 3, b ?? 5, c ?? -1], x: x, key: key);
}

Named constructor parameters are optional. More about using-constructors

  • Related