Home > OS >  Can default values be specified once (in the presence of non-nullable instance variables)?
Can default values be specified once (in the presence of non-nullable instance variables)?

Time:10-12

Consider the following class. It is what we may call a "two-dimensional enum". We could have used an enum with four states, but since the four states have a clear meaning, we choose the more direct approach of storing two Boolean flags.

class FlowerType {
  bool has_scent = false;
  bool has_thorns = false;

  FlowerType({this.has_scent = false, this.has_thorns = false});
}

The class has one constructor with two named optional parameters.

This constructor also acts as a default constructor, and since the two bools are non-nullable, they need to be specified (again) in the constructor.

Can default values be specified once?

Declaring two final static variables for this purpose is one option (though a pretty lousy one). Here I'm wondering whether I'm missing some basic fact about constructors.

CodePudding user response:

I'd remove the default values from the fields:

class FlowerType {
  final bool hasScent;
  final bool hasThorns;
  FlowerType({this.hasScent = false, this.hasThorns = false});
}

The values written as field initializers will always be overridden by the constructor anyway, and they prevent the fields from being final.

You could consider alternatives like multiple constructors:

  FlowerType.plain() : this(hasScent: false, hasThorns: false);
  FlowerType.thorny() : this(hasScent: false, hasThorns: true); 
  FlowerType.scented() : this(hasScent: true, hasThorns: false);
  FlowerType.thornyAndScented() : this(hasScent: true, hasThorns: true);

(I assume there will be more fields and constructor parameters, otherwise you only ever need four instance of the class).

CodePudding user response:

An alternative (albeit a less efficient one) is to make the members non-nullable but to use nullable parameters:

class FlowerType {
  bool has_scent = false;
  bool has_thorns = false;

  FlowerType({bool? has_scent, bool? has_thorns}) {
    this.has_scent = has_scent ?? this.has_scent;
    this.has_thorns = has_thorns ?? this.has_thorns;
  }
}

Drawbacks:

  • Less efficient (the member would be initialized, the argument would be tested, and the member would be reassigned).
  • Members could not be `final.
  • Members would receive their intended value later in the construction process. It wouldn't matter in this example, though.
  •  Tags:  
  • dart
  • Related