Introduction aux classes

Types référence

Un type défini comme classest un type référence. Au moment de l’exécution, quand vous déclarez une variable de type référence, celle-ci contient la valeur null tant que vous n’avez pas explicitement créé une instance de la classe à l’aide de l’opérateur new, ou que vous ne lui avez pas assigné un objet existant d’un type compatible, comme indiqué dans l’exemple suivant :

//Declaring an object of type MyClass.
MyClass mc = new MyClass();

//Declaring another object of the same type, assigning it the value of the first object.
MyClass mc2 = mc;

Quand l’objet est créé, une quantité de mémoire suffisante est allouée sur le tas managé de l’objet spécifié, et la variable contient uniquement une référence à l’emplacement de cet objet. La mémoire utilisée par un objet est récupérée par la fonctionnalité de gestion automatique de la mémoire du CLR, appelée garbage collection. Pour plus d’informations sur le garbage collection, consultez Gestion automatique de la mémoire et garbage collection.

Déclaration de classes

Les classes sont déclarées à l’aide du mot clé class suivi d’un identificateur unique, comme l’illustre l’exemple suivant :

//[access modifier] - [class] - [identifier]
public class Customer
{
   // Fields, properties, methods and events go here...
}

Un modificateur d’accès facultatif précède le mot clé class. Comme public est utilisé dans ce cas, n’importe qui peut créer des instances de cette classe. Le nom de la classe suit le mot clé class. Le nom de la classe doit être un nom d’identificateur C# valide. Le reste de la définition est le corps de la classe, où le comportement et les données sont définis. Les champs, propriétés, méthodes et événements d’une classe sont désignés collectivement par le terme « membres de classe ».

Création d'objets

Bien qu’ils soient parfois employés indifféremment, une classe et un objet sont deux choses différentes. Une classe définit un type d’objet, mais il ne s’agit pas d’un objet en soi. Un objet, qui est une entité concrète basée sur une classe, est parfois désigné par le terme « instance de classe ».

Les objets peuvent être créés à l’aide du mot clé new suivi du nom de la classe, comme suit :

Customer object1 = new Customer();

Quand une instance d’une classe est créée, une référence à l’objet est repassée au programmeur. Dans l’exemple précédent, object1 est une référence à un objet basé sur Customer. Cette référence fait référence au nouvel objet, mais elle ne contient pas ses données. En fait, vous pouvez créer une référence d’objet sans créer d’objet :

Customer object2;

Nous vous déconseillons de créer des références d’objet sans référence à un objet, car toute tentative d’accès à un objet à l’aide d’une telle référence échoue au moment de l’exécution. Vous pouvez créer une telle référence pour faire référence à un objet : soit en créant un objet, soit en l’assignant à un objet existant, comme suit :

Customer object3 = new Customer();
Customer object4 = object3;

Ce code crée deux références d’objet qui font toutes deux référence au même objet. Toute modification apportée à l’objet par le biais de object3 est donc reflétée dans les utilisations suivantes de object4. Les objets qui sont basés sur des classes étant désignés par référence, les classes sont appelées des « types référence ».

Constructeurs et initialisation

Les sections précédentes ont introduit la syntaxe pour déclarer un type de classe et créer une instance de ce type. Lorsque vous créez une instance d’un type, vous souhaitez vous assurer que ses champs et ses propriétés sont initialisés en valeurs utiles. Il existe plusieurs façons d’initialiser des valeurs :

  • Accepter les valeurs par défaut
  • Initialiseurs de champs
  • Paramètres du constructeur
  • Initialiseurs d’objet

Chaque type .NET a une valeur par défaut. En règle générale, cette valeur est 0 pour les types numériques et null pour tous les types de référence. Vous pouvez vous appuyer sur cette valeur par défaut lorsqu’elle est raisonnable dans votre application.

Lorsque la valeur par défaut de .NET n’est pas la bonne, vous pouvez définir une valeur initiale à l’aide d’un initialiseur de champ :

public class Container
{
    // Initialize capacity field to a default value of 10:
    private int _capacity = 10;
}

Vous pouvez exiger que les appelants fournissent une valeur initiale en définissant un constructeur responsable de la définition de cette valeur initiale :

public class Container
{
    private int _capacity;

    public Container(int capacity) => _capacity = capacity;
}

À compter de C# 12, vous pouvez définir un constructeur principal dans le cadre de la déclaration de classe :

public class Container(int capacity)
{
    private int _capacity = capacity;
}

L’ajout de paramètres au nom de classe définit le constructeur principal. Ces paramètres sont disponibles dans le corps de la classe, qui inclut ses membres. Vous pouvez les utiliser pour initialiser des champs ou n’importe où où ils sont nécessaires.

Vous pouvez également utiliser le modificateur required sur une propriété et autoriser les appelants à utiliser un initialiseur d’objet pour définir la valeur initiale de la propriété :

public class Person
{
    public required string LastName { get; set; }
    public required string FirstName { get; set; }
}

L’ajout des mandats de mot clé required que les appelants doivent définir ces propriétés dans le cadre d’une expression new :

var p1 = new Person(); // Error! Required properties not set
var p2 = new Person() { FirstName = "Grace", LastName = "Hopper" };

Héritage de classe

Les classes prennent entièrement en charge l’héritage, caractéristique fondamentale de la programmation orientée objet. Lorsque vous créez une classe, vous pouvez hériter de toute autre classe qui n’est pas définie comme sealed. D’autres classes peuvent hériter de votre classe et remplacer vos méthodes virtuelles de classe. En outre, vous pouvez implémenter une ou plusieurs interfaces.

L’héritage se fait par le biais d’une dérivation, ce qui signifie qu’une classe est déclarée à l’aide d’une classe de base dont elle hérite les données et le comportement. Pour spécifier une classe de base, ajoutez deux-points et le nom de la classe de base après le nom de la classe dérivée, comme suit :

public class Manager : Employee
{
    // Employee fields, properties, methods and events are inherited
    // New Manager fields, properties, methods and events go here...
}

Quand une déclaration de classe inclut une classe de base, elle hérite de tous les membres de la classe de base à l’exception des constructeurs. Pour plus d’informations, consultez Héritage.

Une classe en C# ne peut hériter directement que d’une seule classe de base. Toutefois, une classe de base pouvant elle-même hériter d’une autre classe, une classe peut hériter indirectement de plusieurs classes de base. En outre, une classe peut implémenter directement une ou plusieurs interfaces. Pour plus d'informations, consultez Interfaces.

Une classe peut être déclarée abstract. Une classe abstraite contient des méthodes abstraites qui ont une définition de signature, mais aucune implémentation. Les classes abstraites ne peuvent pas être instanciées. Elles peuvent être utilisées uniquement à travers des classes dérivées qui implémentent les méthodes abstraites. En revanche, une classe sealed ne permet pas à d’autres classes de dériver d’elle. Pour plus d’informations, consultez Classes abstract et sealed, et membres de classe.

Les définitions de classe peuvent être fractionnées entre différents fichiers sources. Pour plus d’informations, consultez la page Classes et méthodes partielles.

Spécification du langage C#

Pour plus d'informations, voir la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.