• 20 hours
  • Medium

Free online content available in this course.

course.header.alt.is_certifying

Got it!

Last updated on 3/10/17

Manipulez des objets

Log in or subscribe for free to enjoy all this course has to offer!

Maintenant que nous avons bien vu comment définir des objets, il est temps de savoir les utiliser.

Nous allons voir dans ce chapitre quelles sont les subtilités de l'instanciation des objets. Vous verrez notamment ce qu'est un constructeur et qu'on peut avoir des valeurs nulles pour des objets.

N'hésitez pas à jouer avec tous ces concepts, il est important d'être à l'aise avec les bases pour pouvoir être efficace avec les concepts avancés.

Le constructeur

Le constructeur est une méthode particulière de l’objet qui permet de faire des choses au moment de la création d’un objet, c’est-à-dire au moment où nous utilisons le mot-clé new.
Il est en général utilisé pour initialiser des valeurs par défaut d’un objet.
Par exemple, si nous voulons que lors de la création d’une voiture, elle ait automatiquement une vitesse, nous pouvons faire :

public class Voiture
{
    public int Vitesse { get; set; }

    public Voiture()
    {
        Vitesse = 5;
    }
}

Le constructeur est en fait une méthode spéciale qui a le même nom que la classe et qui ne possède pas de type de retour. Elle est appelée lors de la création de l’objet, avec new.

Pour illustrer le comportement du constructeur, ajoutons une méthode Rouler à notre classe, de cette façon :

public class Voiture
{
    public int Vitesse { get; set; }

    public Voiture()
    {
        Vitesse = 5;
    }

    public void Rouler()
    {
        Console.WriteLine("Je roule à " + Vitesse + " km/h");
    }
}

Que nous pourrons appeler ainsi :

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

Au moment de l’instanciation de l’objet avec new, la vitesse va être égale à 5. Nous faisons rouler la voiture. Puis nous changeons la vitesse pour la passer à 50 et nous faisons à nouveau rouler la voiture.
Nous aurons :

Image utilisateur

Le constructeur est la première « méthode » à être appelée lors de la création d’un objet. C’est l’endroit approprié pour faire des initialisations, ou pour charger des valeurs, etc.

Le constructeur que nous avons vu est ce qu’on appelle le constructeur par défaut, car il ne possède pas de paramètres.
Il est possible de passer des paramètres à un constructeur, pour initialiser des variables de notre classe avec des valeurs. Pour ce faire, nous devons déclarer un constructeur avec un paramètre ; par exemple :

public class Voiture
{
    public int Vitesse { get; set; }

    public Voiture()
    {
        Vitesse = 5;
    }

    public Voiture(int vitesse)
    {
        Vitesse = vitesse;
    }

    public void Rouler()
    {
        Console.WriteLine("Je roule à " + Vitesse + " km/h");
    }
}

Ainsi, nous pourrons créer un objet voiture en lui précisant une vitesse par défaut de cette façon :

Voiture voitureNicolas = new Voiture(20);

Après ceci, la variable voitureNicolas aura une vitesse de 20.

Bien sûr, nous pourrions faire la même chose sans utiliser de constructeur, en affectant une valeur à la propriété après avoir instancié l’objet. Ce qui fonctionnerait tout à fait.
Sauf qu’il ne se passe pas exactement la même chose. Le constructeur est vraiment appelé en premier, dès qu’on utilise new pour créer un objet. Les propriétés sont affectées fatalement après, donc tout dépend de ce que l’on veut faire.

Donc, oui, on pourrait affecter une valeur à des propriétés pour faire ce genre d’initialisation juste après avoir instancié notre objet mais cela nous oblige à écrire une instruction supplémentaire qui pourrait ne pas paraitre évidente ou obligatoire.

Une chose est sûre avec le constructeur, c’est que nous sommes obligés d’y passer et ceci, peu importe la façon dont on utilise la classe.
L’initialisation devient donc obligatoire, on évite le risque qu’une propriété soit nulle.

À noter qu’il est possible de cumuler les constructeurs tant qu’ils ont chacun des paramètres différents. Dans notre exemple, nous pourrons donc créer des voitures de deux façons différentes :

Voiture voitureNicolas = new Voiture(); // vitesse vaut 5
Voiture voitureJeremie = new Voiture(20); // vitesse vaut 20

Il est aussi possible de ne pas définir de constructeur par défaut et d’avoir uniquement un constructeur possédant des paramètres.
Dans ce cas, il devient impossible d’instancier un objet sans lui passer de paramètres.

Instancier un objet

Nous allons revenir à présent sur l’instanciation d’un objet. Comme nous venons de le voir, nous utilisons le mot clé new pour créer une instance d’un objet. C’est lui qui permet la création d’un objet. Il appelle le constructeur correspondant. Si aucun constructeur n’existe, il ne se passera rien de plus qu’une création de base. Par exemple :

Voiture voitureNicolas = new Voiture();

Pour rentrer un peu dans la technique, au moment de l’instanciation d’un objet, l’opérateur new crée l’objet et le met à une place disponible en mémoire. Cette adresse mémoire est conservée dans la variable voitureNicolas. On dit que voitureNicolas contient une référence vers l’objet. Nous verrons un peu plus tard ce que cela implique.

Comme pour les types que nous avons vus plus haut, nous sommes obligés d’initialiser un objet avant de l’utiliser. Sinon, Visual Studio Express nous génèrera une erreur de compilation. Par exemple, les instructions suivantes :

Voiture voitureNicolas;
voitureNicolas.Vitesse = 5;

provoqueront l’erreur de compilation suivante :

Utilisation d'une variable locale non assignée 'voitureNicolas'        

En effet, Visual Studio Express est assez intelligent pour se rendre compte que l’on va essayer d’accéder à un objet qui n’a pas été initialisé.

Il faut toujours initialiser une variable avant de pouvoir l’utiliser. Comme pour les types précédents, il est possible de dissocier la déclaration d’un objet de son instanciation, en écrivant les instructions sur plusieurs lignes, par exemple :

Voiture voitureNicolas;
// des choses
voitureNicolas = new Voiture();

ceci est possible tant que nous n’utilisons pas la variable voitureNicolas avant de l’avoir instanciée.

Les objets peuvent également avoir une valeur nulle. Ceci est différent de l’absence d’initialisation car la variable est bien initialisée et sa valeur vaut « nul ». Ceci est possible grâce à l’emploi du mot-clé null.

Voiture voitureNicolas = null;

Attention, il est par contre impossible d’accéder à un objet qui vaut null. Eh oui, comment voulez-vous vous asseoir sur une chaise qui n’existe pas ?
Eh bien vous vous retrouverez avec les fesses par terre, personne ne vous a indiqué que la chaise n’existait pas. ;)

C’est pareil pour notre application, si nous tentons d’utiliser une voiture qui n’existe pas, nous aurons droit à un beau plantage.

Par exemple, avec le code suivant :

Voiture voitureNicolas = null;
voitureNicolas.Vitesse = 5;

vous n’aurez pas d’erreur à la compilation, par contre vous aurez :

Image utilisateur

Comme nous l’avons déjà vu, le programme nous affiche une exception ; nous avons dit que c’était simplement une erreur qui faisait planter notre programme.
Pas bien ! Surtout que cela se passe au moment de l’exécution. Nous perdons toute crédibilité !

Ici, le programme nous dit que la référence d’un objet n’est pas définie à une instance d’un objet.
Concrètement, cela veut dire que nous essayons de travailler sur un objet null.

Pour éviter ce genre d’erreur à l’exécution, il faut impérativement instancier ses objets, en utilisant l’opérateur new, comme nous l’avons déjà vu.
Il n’est cependant pas toujours pertinent d’instancier un objet dont on pourrait ne pas avoir besoin. Le C# nous offre donc la possibilité de tester la nullité d’un objet. Il suffit d’utiliser l’opérateur de comparaison « == » en comparant un objet au mot-clé null, par exemple :

string prenom = "Nicolas";
Voiture voiture = null;
if (prenom == "Nicolas")
    voiture = new Voiture { Vitesse = 50 };
if (voiture == null)
{
    Console.WriteLine("Vous n'avez pas de voiture");
}
else
{
    voiture.Rouler();
}

Ainsi, seul Nicolas possédera une voiture et le test de nullité sur l’objet permet d’éviter une erreur d’exécution si le prénom est différent.

Maintenant que vous connaissez le mot-clé null et que vous savez qu’un objet peut prendre une valeur nulle, nous allons revenir sur un point que j’ai rapidement abordé dans le cours précédent.
Je ne sais pas si vous vous en rappelez, mais lors de l’étude des opérateurs logiques j’ai parlé du fait que l’opérateur OU ( || ) évaluait la première condition et si elle était vraie alors il n’évaluait pas la suivante, considérant que de toutes façons, le résultat allait être vrai.

Ce détail prend toute son importance dans le cas suivant :

if (voiture == null || voiture.Couleur == "Bleue")
{
    // faire quelque chose
}

Dans ce cas, si la voiture est effectivement nulle, alors le fait d’évaluer la propriété Couleur de la voiture devrait renvoyer une erreur. Heureusement, le C# avait prévu le coup, si la première condition est vraie alors la seconde ne sera pas évaluée, ce qui évitera l’erreur. Ainsi, nous sommes sûrs de n’avoir aucune voiture bleue.

Il est par contre évident qu’une telle condition utilisant l’opérateur ET (&&) est une hérésie car pour que la condition soit vraie, le C# a besoin d’évaluer les deux opérandes. Et donc si la voiture est nulle, l’utilisation d’une propriété sur une valeur nulle renverra une erreur.

Notons également que lorsque nous utilisons l’opérateur ET (&&) si la première opérande est fausse, alors de la même façon, il n’évalue pas la seconde, car pour que la condition soit vraie il faut que les deux le soient.
Ce qui fait qu’il est également possible d’écrire ce code :

if (voiture != null && voiture.Couleur == "Rouge")
{
	// faire autre chose
}

qui ne provoquera pas d’erreur à l’exécution, même si voiture vaut null car dans ce cas, le fait que le premier test soit faux évitera le test de l’autre partie de l’expression.

Vous verrez que vous aurez l’occasion d’utiliser le mot-clé null régulièrement.

Le mot-clé this

Lorsque nous écrivons le code d’une classe, le mot-clé this représente l’objet dans lequel nous nous trouvons. Il permet de clarifier éventuellement le code, mais Il est généralement facultatif.
Ainsi, pour accéder à une variable de la classe ou éventuellement une méthode, nous pouvons les préfixer par « this. ». Par exemple, nous pourrions écrire notre classe de cette façon :

public class Voiture
{
    public int Vitesse { get; set; }
    public string Couleur { get; set; }

    public Voiture()
    {
        this.Vitesse = 5;
    }

    public void Rouler()
    {
        Console.WriteLine("Je roule à " + this.Vitesse + " km/h");
    }

    public void Accelerer(int acceleration)
    {
        this.Vitesse += acceleration;
        this.Rouler();
    }
}

Ici, dans le constructeur, nous utilisons le mot-clé this pour accéder à la propriété Vitesse. C’est la même chose dans la méthode Rouler. De la même façon, on peut utiliser this.Rouler() pour appeler la méthode Rouler depuis la méthode Accelerer().

C’est une façon pour la classe de dire : « Regardez, avec this, c’est "ma variable à moi" ».

Notez bien sûr que sans le mot-clé this, notre classe compilera quand même et sera tout à fait fonctionnelle. Ce mot-clé est facultatif mais il peut aider à bien faire la différence entre ce qui appartient à la classe et ce qui fait partie des paramètres des méthodes ou d’autres objets utilisés.

Suivant les personnes, le mot-clé this est soit systématiquement utilisé, soit jamais. Je fais plutôt partie des personnes qui ne l’utilisent jamais.
Il arrive par contre certaines situations où il est absolument indispensable, comme celle-ci, mais en général, j’essaie d’éviter ce genre de construction :

public void ChangerVitesse(int Vitesse)
{
    this.Vitesse = Vitesse;
}

Vous remarquerez que le paramètre de la méthode ChangerVitesse() et la propriété ou variable membre de la classe ont exactement le même nom. Ceci est possible ici mais source d’erreurs, les variables ayant des portées différentes. Il s’avère que dans ce cas, le mot-clé this est indispensable.
On pourra donc éviter l’ambigüité en préfixant la propriété membre avec le mot-clé this.

Je recommande plutôt de changer le nom du paramètre, quitte à utiliser une minuscule, ce qui augmentera la lisibilité et évitera des erreurs potentielles.

En général, des conventions de nommage pourront nous éviter de nous retrouver dans ce genre de situation.

Ça y est, nous savons instancier et utiliser des objets.

Savoir créer et utiliser ses propres objets est très important dans un programme orienté objet.

Vous allez également avoir besoin très régulièrement d’utiliser des objets tout fait, comme ceux venant de la bibliothèque de classe du framework .NET. Nous comprenons d’ailleurs mieux pourquoi elle s’appelle « bibliothèque de classes ». Il s’agit bien d’un ensemble de classes utilisables dans notre application et nous pourrons instancier les objets relatifs à ces classes pour nos besoins. Comme ce que nous avions déjà fait auparavant sans trop le savoir, avec l’objet Random par exemple…

N’hésitez pas à relire ce chapitre ainsi que le précédent si vous n’avez pas parfaitement compris toutes les subtilités de la création d’objet. C’est un point important du tutoriel.

Cependant, nous n’avons pas encore tout vu sur le C# et la POO. Alors ne nous arrêtons pas en si bon chemin et attaquons des concepts un peu plus avancés.

En résumé
  • Les classes possèdent une méthode particulière, appelée à l'instanciation de l'objet : le constructeur.

  • Une instance d'une classe peut être initialisée avec une valeur nulle grâce au mot-clé null.

  • Le mot-clé this représente l'objet en cours de la classe.

Example of certificate of achievement
Example of certificate of achievement