Closed Hari-07 closed 4 days ago
Since Person are a public class, it can be overwritten in a later subclass (in another library that imports your code). Since final
values really just means this value only have a getter, we are allowed to override Person
here with:
class SuspiciousPerson extends Person {
bool first = true;
@override
String? get name {
if (first) {
first = false;
return 'James Bond';
} else {
return null;
}
}
}
void main() {
final a = SuspiciousPerson();
a.printName();
// Unhandled exception:
// Null check operator used on a null value
}
Because of this, we cannot ensure that name
are going to have the same value if you ask for it twice. The solution are instead here to only ask for it once, and then reuse this value like:
String printName() {
if (name case final name?) return name;
return 'User';
}
Here, we declare a new non-null variable called name
that contains the value of the class variable name
in case it is not null. See: https://dart.dev/language/pattern-types#null-check
Alternative, if the name
variable in your class are defined as private (_name
) then it can't no longer be overridden by an unknown subclass, and Dart can therefore ensure the stability of the field and make this valid:
class Person {
final String? _name;
Person([String? name]) : _name = name;
String printName() {
if (_name != null) return _name;
return 'User';
}
}
@julemand101's explanation in on point.
@Hari-07 please refer to https://dart.dev/tools/non-promotion-reasons to understand limitations of promotion.
Thank you both, that does make sense. I hadn't thought of a final as a field that just has a getter but not a setter, and therefore isn't guaranteed to return the same value in a given instance but it does make sense. Very interesting
Consider this code for example. When the class is initialized since name is final, it can be determined statically that for this instance of the object the field name can't be changed anymore since its a final.
So then in the printName method, why does the analyzer require me to assert its non null