Partager via


interface (Informations de référence sur C#)

Une interface définit un contrat. Tout class, recordou struct qui implémente ce contrat doit fournir une implémentation des membres définis dans l’interface.

Une interface peut définir une implémentation par défaut pour un membre. Il peut également définir des static membres pour fournir une implémentation unique pour les fonctionnalités courantes.

Une interface peut définir ou static virtual des static abstract membres pour déclarer qu’un type d’implémentation doit fournir les membres déclarés. En règle générale, les méthodes static virtual déclarent qu’une implémentation doit définir un ensemble d’opérateurs surchargés.

Dans l’exemple suivant, la classe ImplementationClass doit implémenter une méthode nommée SampleMethod qui n’a aucun paramètre et qui retourne void.

interface ISampleInterface
{
    void SampleMethod();
}

class ImplementationClass : ISampleInterface
{
    // Explicit interface member implementation:
    void ISampleInterface.SampleMethod()
    {
        // Method implementation.
    }

    static void Main()
    {
        // Declare an interface instance.
        ISampleInterface obj = new ImplementationClass();

        // Call the member.
        obj.SampleMethod();
    }
}

Pour plus d’informations et d’exemples, consultez Interfaces.

Modificateurs d’accès

Une interface peut être membre d’un espace de noms ou d’une classe. Une interface de haut niveau, déclarée dans un espace de noms sans être imbriquée dans un autre type, peut être déclarée public ou internal. Par défaut, il s’agit de internal. Les déclarations d’interface imbriquées, déclarées à l’intérieur d’un autre type, peuvent être déclarées à l’aide de n’importe quel modificateur d’accès.

Les membres d’interface sans implémentation (membres abstraits) sont implicitement public et ne peuvent pas avoir d’autre modificateur d’accès. Les membres de l’interface avec une implémentation par défaut sont private par défaut si aucun modificateur d’accès n’est spécifié, mais peut être déclaré avec n’importe quel modificateur d’accès (public, , privateprotectedou internal).

Membres d’interfaces

Une déclaration d’interface peut contenir les membres suivants :

Membres d’interface par défaut

Les déclarations de membre ne contiennent généralement pas de corps. Toutefois, un membre d’interface peut déclarer un corps. Les corps membres d’une interface sont l’implémentation par défaut. Les membres dotés de corps permettent à l’interface de fournir une implémentation « par défaut » pour les classes et les structs qui ne fournissent pas d’implémentation de remplacement.

Important

L’ajout de membres d’interfaces par défaut applique les ref struct qui implémentent l’interface pour ajouter une déclaration explicite de ce membre.

Membres virtuels et abstraits statiques

Une interface peut déclarer static abstract et static virtual membres pour tous les types de membres, à l’exception des champs. Les interfaces peuvent déclarer que les types d’implémentation doivent définir des opérateurs ou d’autres membres statiques. Cette fonctionnalité permet aux algorithmes génériques de spécifier le comportement de type nombre. Vous pouvez voir des exemples dans les types numériques dans le runtime .NET, par exemple System.Numerics.INumber<TSelf>. Ces interfaces définissent des opérateurs mathématiques courants implémentés par de nombreux types numériques. Le compilateur doit résoudre les appels aux méthodes static virtual et static abstract au moment de la compilation. Les méthodes static virtual et static abstract déclarées dans les interfaces n’ont pas de mécanisme de répartition d’exécution analogue aux méthodes virtual ou abstract déclarées dans les classes. Au lieu de cela, le compilateur utilise des informations de type disponibles au moment de la compilation. Par conséquent, les méthodes static virtual sont presque exclusivement déclarées dans les interfaces génériques. En outre, la plupart des interfaces qui déclarent les méthodes static virtual ou static abstract notifient que l’un des paramètres de types doit implémenter l’interface déclarée. Par exemple, l’interface INumber<T> déclare que T doit implémenter INumber<T>. Le compilateur utilise l’argument de type pour résoudre les appels aux méthodes et opérateurs déclarés dans la déclaration d’interface. Par exemple, le type int implémente INumber<int>. Lorsque le paramètre de type T désigne l’argument de type int, les membres static déclarés dans int sont appelés. Sinon, si double est l’argument de type, les membres static déclarés dans le type double sont appelés.

Important

La répartition des méthodes static abstract et static virtual déclarées dans les interfaces est résolue à l’aide du type de temps de compilation d’une expression. Si le type d’exécution d’une expression est dérivé d’un type de temps de compilation différent, les méthodes statiques sur le type de base (heure de compilation) sont appelées.

Vous pouvez essayer cette fonctionnalité en travaillant avec le tutoriel sur les membres abstraits statiques dans les interfaces.

Héritage de l'interface

Les interfaces ne peuvent pas contenir d’état d’instance. Bien que les champs statiques soient désormais autorisés, les champs d’instance ne sont pas autorisés dans les interfaces. Les propriétés automatiques d’instance ne sont pas prises en charge dans les interfaces, car elles déclareraient implicitement un champ masqué. Cette règle a un effet subtil sur les déclarations de propriété. Dans une déclaration d’interface, le code suivant ne déclare pas une propriété implémentée automatiquement comme elle le fait dans un class ou struct. À la place, il déclare une propriété qui n’a pas d’implémentation par défaut, mais doit être implémentée dans n’importe quel type qui implémente l’interface :

public interface INamed
{
  public string Name {get; set;}
}

Une interface peut hériter d’une ou de plusieurs interfaces de base. Lorsqu’une interface hérite d’une autre interface, un type implémentant l’interface dérivée doit implémenter tous les membres des interfaces de base en plus de ces membres déclarés dans l’interface dérivée, comme indiqué dans le code suivant :

public interface I1
{
    void M1();
}

public interface I2 : I1
{
    void M2();
}

public class C : I2
{
    // implements I1.M1
    public void M1() { }
    // implements I2.M2
    public void M2() { }
}

Lorsqu’une interface remplace une méthode implémentée dans une interface de base, elle doit utiliser la syntaxe d’implémentation d’interface explicite.

Lorsqu’une liste de types de base contient une classe de base et des interfaces, la classe de base doit figurer en premier dans la liste.

Une classe qui implémente une interface peut implémenter explicitement les membres de cette interface. Un membre implémenté explicitement n’est pas accessible via une instance de classe, mais uniquement via une instance de l’interface. En outre, les membres de l’interface par défaut sont accessibles uniquement via une instance de l’interface.

Pour plus d’informations sur l’implémentation d’interface explicite, consultez Implémentation d’interface explicite.

Exemple d’implémentation d’interface

L’exemple suivant montre une implémentation d’interface. Dans cet exemple, l’interface contient la déclaration de propriété, et la classe contient l’implémentation. Toutes les instances d’une classe qui implémentent IPoint ont les propriétés entières x et y.

interface IPoint
{
    // Property signatures:
    int X { get; set; }

    int Y { get; set; }

    double Distance { get; }
}

class Point : IPoint
{
    // Constructor:
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    // Property implementation:
    public int X { get; set; }

    public int Y { get; set; }

    // Property implementation
    public double Distance =>
       Math.Sqrt(X * X + Y * Y);
}

class MainClass
{
    static void PrintPoint(IPoint p)
    {
        Console.WriteLine("x={0}, y={1}", p.X, p.Y);
    }

    static void Main()
    {
        IPoint p = new Point(2, 3);
        Console.Write("My Point: ");
        PrintPoint(p);
    }
}
// Output: My Point: x=2, y=3

spécification du langage C#

Pour plus d’informations, consultez la section Interfaces de la spécification du langage C# et la spécification de fonctionnalité pour les membres abstraits statiques dans les interfaces.

Voir aussi