devstory

Propriétés en Dart

  1. Qu'est-ce qu'une propriété?
  2. Getter
  3. Setter
  4. Examples

1. Qu'est-ce qu'une propriété?

Avant de définir ce que c'est une propriété, il est nécessaire de clarifier ce que c'est un champ (field).
Un champ (field) est une variable déclarée directement dans une classe.
Voir l'articile sur le constructeur pour mieux comprendre comment Dart assigne les valeurs aux champs.
  • Dart Constructors
Dans le langage Dart, tous les champs de la classe sont accessibles depuis l'extérieur de la classe. Il est possible d'obtenir leurs valeurs et de leur en définir les nouvelles. Par exemple:
field_ex1.dart
class Person {
  String name;
  String gender;
  String? country; // Allow null value.

  Person(this.name, this.gender, this.country); // Constructor
  Person.nameAndGender(this.name, this.gender); // Constructor

  // Method:
  void selfIntroduce() {
    if (country != null) {
      print('Hi, My name is $name, from $country');
    } else {
      print('Hi, My name is $name');
    }
  }
}

void main() {
  Person emma = new Person('Emma', 'Female', 'USA'); // Create an object
  emma.selfIntroduce(); // Call method.

  var name = emma.name; // get the value of a field

  print('emma.name: $name');
  print('emma.gender: ${emma.gender}');
  print('emma.country: ${emma.country}');

  print(' --- Set new value to country field ---: ');

  emma.country = 'Canada'; // set new value to a field
  print('emma.country: ${emma.country}');
}
Output:
Hi, My name is Emma, from USA
emma.name: Emma
emma.gender: Female
emma.country: USA
 --- Set new value to country field ---:
emma.country: Canada
Private Field?
A la différence de Java, Dart ne fournit pas les mots clefs private, protected et public. Si vous souhaitez obtenir un private field, il faut nommer ce champs en débutant avec un trait de soulignement ( _ ). Par exemple _fieldName.
Les champs dont les noms commencent par un trait de soulignement ( _ ) sont implicitement private, ils sont utilisés en interne par la bibliothèque. Il s'agit simplement d'une convention implicite, les programmeurs utilisant la bibliothèque ne doivent pas accéder à ces champs de l'extérieur, car cela contrevient à l'idée de conception de bibliothèque. L'accès intentionnel à ces champs depuis l'extérieur risque de provoquer des erreurs inattendues.
Property?
En règle générale, lorsque vous rencontrez un champs quelque part, il est possible de récupérer sa valeur et de lui en assigner une nouvelle.
La propriété est un concept similaire à un champ (field), mais elle dispose des caractéristiques beaucoup plus spéciales. La propriété est divisée en 3 types:
  • Read-only Property: Autoriser l'accès à ses valeurs, mais ne pas autoriser à lui en définir les nouvelles.
  • Write-only Property: Autoriser à lui définir une nouvelle valeur, mais ne pas autoriser à accéder à ses valeurs.
  • Read/Write Property: Autoriser l'accès à la valeur, et autoriser à lui déterminer une nouvelle valeur.
Conformément à l'idée de conception de Dart, vous devez nommer tous les champs de votre classe en commençant par un trait de soulignement ( _ ), cela signifie qu'ils ne sont utilisés qu'en interne par la bibliothèque et utilisent des propriétés pour remplacer le rôle des champs dans la communication avec le monde extérieur.

2. Getter

La syntaxe Getter vous permet de définir une propriété en dehors de la classe qui peut accéder à sa valeur, mais elle ne peut pas lui définir une nouvelle valeur à moins que vous ne définissiez également un Setter pour cette propriété.
data_type get property_name {
     // code ...
     return a_value;
}
Par exemple, la classe Person ci-dessous permet d'accéder à la valeur du name de la propriété mais ne permet pas de modifier sa valeur de l'extérieur.
property_getter_ex1.dart
class Person {
  String _name; // private field
  String gender;
  String? _country; // private field

  Person(this._name, this.gender, this._country); // Constructor
  Person.nameAndGender(this._name, this.gender); // Constructor
  // Getter
  String get name {
    return _name;
  }

  // Getter
  String get country {
    return _country ?? '[Not Provided]';
  }

  // Method:
  void selfIntroduce() {
    if (_country != null) {
      print('Hi, My name is $name, from $country');
    } else {
      print('Hi, My name is $name');
    }
  }
}

void main() {
  var emma = Person.nameAndGender('Emma', 'Female'); // Create an object
  emma.selfIntroduce(); // Call method.

  var name = emma.name; // get the value of a property
  var country = emma.country; // get the value of a property
  print('emma.name: $name');
  print('emma.country: $country');

  // Can not set new value to property - name
  // emma.name = 'New Name'; // ERROR!!
}
Output:
Hi, My name is Emma
emma.name: Emma
emma.country: [Not Provided]

3. Setter

La syntaxe Setter vous permet de définir une propriété qui autorise à définir une nouvelle valeur pour elle, mais n'autorise pas l'accès à sa valeur à moins que vous ne définissiez également un Getter pour cette propriété.
set property_name(data_type newValue)  {
     // code
}
Par exemple:
property_setter_ex1.dart
class Person {
  String name;
  String gender;
  String _country; // private field

  Person(this.name, this.gender, this._country); // Constructor

  // Setter
  set country(String newCountry) {
    _country = newCountry;
  }

  // Method:
  void selfIntroduce() {
    print('Hi, My name is $name, from $_country');
  }
}

void main() {
  var emma = Person('Emma', 'Female', 'USA'); // Create an object
  emma.selfIntroduce(); // Call method.

  // Set new value to country property.
  emma.country = 'Canada';
  emma.selfIntroduce();

  // Can not get the value of country property
  // var country = emma.country; // ERROR!!
}
Output:
Hi, My name is Emma, from USA
Hi, My name is Emma, from Canada

4. Examples

Par exemple: Une propriété avec Getter et Setter en même temps:
property_gettersetter_ex1.dart
class Person {
  String name;
  String gender;
  String? _country; // private field

  Person(this.name, this.gender, this._country); // Constructor
  Person.nameAndGender(this.name, this.gender); // Constructor

  // Getter
  String get country {
    return _country ?? '[Not Provided]';
  }

  // Setter
  set country(String newCountry) {
    _country = newCountry;
  }

  // Method:
  void selfIntroduce() {
    if(_country != null)  {
        print('Hi, My name is $name, from $_country');
    } else {
      print('Hi, My name is $name');
    }
    
  }
}

void main() {
  var emma = Person.nameAndGender('Emma', 'Female'); // Create an object
  emma.selfIntroduce(); // Call method.
  var country = emma.country;
  print('Country: $country');

  print(' --- set new value to country property ---');

  emma.country = 'Canada'; // Set new value to country property.
  emma.selfIntroduce();
}
Output:
Hi, My name is Emma
emma.country: [Not Provided]
 --- set new value to country property ---
Hi, My name is Emma, from Canada