Flutter for Beginners
上QQ阅读APP看书,第一时间看更新

Field accessors – getters and setters

As mentioned previously, getters and setters allow us to access a field on a class, and every field has these accessors, even when we do not define them. In the preceding Person example, when we execute somePerson.firstName = "Peter", we are calling the firstName field's set accessor and sending "Peter" as a parameter to it. Also in the example, the get accessor is used when we call the getFullName() method on the person, and it concatenates both names.

We can modify our Person class to replace the old getFullName() method and add it as a getter, as demonstrated in the following code block, for example:

class Person {
String firstName;
String lastName;

Person(this.firstName, this.lastName);

Person.anonymous() {}

String get fullName => "$firstName $lastName";
String get initials => "${firstName[0]}. ${lastName[0]}.";
}

main() {
Person somePerson = new Person("clark", "kent");

print(somePerson.fullName); // prints clark kent
print(somePerson.initials); // prints c. k.

somePerson.fullName = "peter parker";
// we have not defined a setter fullName so it doesn't compile
}

The following important observations can be made regarding the preceding example:

  • We could not have defined a getter or setter with the same field names: firstName and lastName. This would give us a compile error, as the class member names cannot be repeated.
  • The initials getter would throw an error for a person instantiated by the anonymous named constructor, as it would not have firstName and lastName values (equates to null).
  • We do not need to always define the pair, get and set, together, as you can see that we have only defined a fullName getter and not a setter, so we cannot modify fullName. (This results in a compilation error, as indicated previously.)

We could have also written a setter for fullName and defined the logic behind it to set firstName and lastName based on that:

class Person {
// ... class fields definition

set fullName(String fullName) {
var parts = fullName.split(" ");
this.firstName = parts.first;
this.lastName = parts.last;
}
}

This way, someone could initialize a person's name by setting fullName and the result would be the same. (Of course, we have not carried out any checks to establish whether the value passed as fullName is valid, that is, not empty, with two or more values, and so on.)