• Aucun résultat trouvé

Les propriétés sont en fait des variables évoluées. Elles sont à mi-chemin entre une variable et une méthode. Prenons cet exemple :

Code : C#

public class Voiture {

private int vitessePrivee; public int Vitesse

{ get { return vitessePrivee; } set { vitessePrivee = value; } } }

Nous pouvons voir que nous définissons dans un premier temps une variable privée, « vitessePrivee » de type entier. Comme prévu, cette variable est masquée pour les utilisateurs d’objets Voiture. Ainsi, le code suivant :

Code : C#

Voiture voitureNicolas = new Voiture(); voitureNicolas.vitessePrivee = 50; provoquera l’erreur de compilation désormais bien connue :

Code : Console

Par contre, nous en avons profité pour définir la propriété Vitesse, de type int. Pour ceci, nous avons défini une partie de la propriété avec le mot clé get suivi d’un return vitessePrivee. Et juste en dessous, nous avons utilisé le mot clé set, suivi de vitessePrivee = value.

Ce que nous avons fait, c’est définir la possibilité de lire la propriété grâce au mot clé get. Ici, la lecture de la propriété nous renvoie la valeur de la variable privée. De la même façon, nous avons défini la possibilité d’affecter une valeur à la propriété en utilisant le mot clé set et en affectant la valeur à la variable privée.

Les blocs de code délimités par get et set se comportent un peu comme des méthodes, elles ont un corps qui est délimité par des accolades et dans le cas du get, elle doit renvoyer une valeur du même type que la propriété.

À noter que dans le cas du set, « value » est un mot clé qui permet de dire : « la valeur que nous avons affectée à la propriété ».

Prenons l’exemple suivant : Code : C#

Voiture voitureNicolas = new Voiture(); voitureNicolas.Vitesse = 50;

Console.WriteLine(voitureNicolas.Vitesse);

La première instruction instancie bien sûr une voiture.

La deuxième instruction consiste à appeler le bloc de code set de Vitesse qui met la valeur 50 dans la pseudo-variable value

qui est stockée ensuite dans la variable privée.

Lorsque nous appelons la troisième instruction, nous lisons la valeur de la propriété et pour ce faire, nous passons par le get

qui nous renvoie la valeur de la variable privée.

Ok, c’est super, mais dans ce cas, pourquoi passer par une propriété et pas par une variable ? Même s'il parait que les variables ne doivent jamais être publiques …

Eh bien parce que dans ce cas-là, la propriété peut faire un peu plus que simplement renvoyer une valeur. Et aussi parce que nous masquons la structure interne de notre classe à ceux qui veulent l’utiliser.

Nous pourrions très bien envisager d’aller lire la vitesse dans les structures internes du moteur, ou en faisant un calcul poussé par rapport au coefficient du vent et de l’âge du capitaine (ou plus vraisemblablement en allant lire la valeur en base de données). Et ici, nous pouvons tirer parti de la puissance des propriétés pour masquer tout ça à l’appelant qui lui n’a besoin que d’une vitesse.

Par exemple : Code : C#

private int vitessePrivee;

public int Vitesse {

get

{

int v = vitesseDesRoues * rayon * coefficient; // ce calcul est complètement farfelu !

MettreAJourLeCompteur(); AdapterLaVitesseDesEssuieGlaces(); return v; } set {

// faire la mise à jour des variables internes

MettreAJourLeCompteur();

AdapterLaVitesseDesEssuieGlaces(); }

}

En faisant tout ça dans le bloc de code get, nous masquons les rouages de notre classe à l’utilisateur. Lui, il n’a besoin que d’obtenir la vitesse, sans s’encombrer du compteur ou des essuie-glaces.

Bien sûr, la même logique peut s’adapter au bloc de code qui permet d’affecter une valeur à la propriété, set.

Il est également possible de rendre une propriété en lecture seule, c’est-à-dire non modifiable par les autres objets. Il pourra par exemple sembler bizarre de positionner une valeur à la vitesse alors qu’en fait, pour mettre à jour la vitesse, il faut appeler la méthode AppuyerPedale(double forceAppui).

Pour empêcher les autres objets de pouvoir directement mettre à jour la propriété Vitesse, il suffit de ne pas déclarer le bloc de code set et de ne garder qu’un get. Par exemple :

Code : C#

public class Voiture {

private int vitessePrivee; public int Vitesse

{

get

{

// faire des calculs ...

return vitessePrivee; }

} }

Ce qui fait que si nous tentons d’affecter une valeur à la propriété Vitesse depuis une autre classe, par exemple : Code : C#

Voiture voitureNicolas = new Voiture(); voitureNicolas.Vitesse = 50;

Nous aurons l’erreur de compilation suivante : Code : Console

La propriété ou l'indexeur 'MaPremiereApplication.Voiture.Vitesse' ne peut pas être assigné - - il est en lecture seule

Le compilateur nous indique donc très justement qu’il est impossible de faire cette affectation car la propriété est en lecture seule.

Il devient donc impossible pour un utilisateur de cette classe de modifier la vitesse de cette façon.

De même, il est possible de définir une propriété pour qu’elle soit accessible en écriture seule. Il suffit de définir uniquement le bloc de code set :

private double acceleration;

public double Acceleration { set { acceleration = value; } }

Ainsi, si nous tentons d’utiliser la propriété en lecture, avec par exemple : Code : C#

Console.WriteLine(voitureNicolas.Acceleration);

Nous aurons l’erreur de compilation attendue : Code : Console

La propriété ou l'indexeur 'MaPremiereApplication.Voiture.Acceleration' ne peut pas être utilisé dans ce contexte, car il lui manque l'accesseur get

Ce bridage d’accès à des propriétés prend tout son sens quand nous souhaitons exposer nos objets à d’autres consommateurs qui n’ont aucun intérêt à connaitre la structure interne de notre classe. C’est un des principes de l’encapsulation.