How to override nullable field with non-nullable one dart

Viewed 261

I have a class with a nullable property. I would like to make a superclass that overrides that property with a non nullable one

so

class Example {
String? name;
}

class NamedExample extends Example {
@override
String name;

}

Is there some way to do that? if not how is this goal conventionally accomplished.

I basically want two identical classes except one of them always has a property while it is optional in another.

2 Answers

This is a place for the covariant keyword. Normally it does not make sense to override a parameter's type with its subtype and it is invalid to do so. This keyword tells the analyzer this is intentional. It can be added in either the super or subclass.

Subclass:

class Example {
  String? name;
}

class NamedExample extends Example {
  @override
  covariant String name;
  
  NamedExample(this.name);
}

Superclass:

class Example {
  covariant String? name;
}

class NamedExample extends Example {
  @override
  String name;
  
  NamedExample(this.name);
}

The reason why you can't override the String? name member with String name is because it can violate the contract of the setter in the base class and therefore could be unsafe. The base class advertises that:

var example = Example();
example.name = null;

is legal. However, if example instead is an instance of NamedExample, the example.name = null assignment would no longer be legal. The covariant keyword disables this safety check and trusts that you will never perform such an assignment in practice.

In general, you should avoid overriding fields.

You could safely have the override if your classes expose only a getter. Both of the following examples would be legal and safe:

class Example {
  String? _optionalName;
  String? get name => _optionalName;
}

class NamedExample extends Example {
  NamedExample(this._requiredName);

  String _requiredName;

  @override
  String get name => _requiredName;
}

or

class Example {
  Example([this.name]);

  final String? name;
}

class NamedExample extends Example {
  NamedExample(this.name);

  @override
  final String name;
}
Related