TOC

This article has been localized into French by the community.

Classes:

Interfaces

Dans les chapitres précédents, nous avons abordé les classes abstraites. Les interfaces ressemblent beaucoup aux classes abstraites et partagent le fait qu'une interface, comme une classe abstraite, ne peut être instanciée. Cependant, les interfaces se situent encore plus au niveau conceptuel que les classes abstraites, car aucun corps de méthode n'est autorisé. Ainsi, une interface est un peu comme une classe abstraite avec seulement des méthodes abstraites, et, comme les méthodes n'ont pas de code réel, une interface ne nécessite pas de membres. Les propriétés sont toutefois autorisées, ainsi que les indexeurs et les événements. Vous pouvez considérer une interface comme un contrat : la classe qui en hérite est tenue d'implémenter toutes les méthodes et propriétés de celle-ci. Cependant, la différence la plus importante est que l'héritage multiple est autorisé pour les interfaces, contrairement aux classes pour lesquelles il ne l'est pas en C#! Une interface peut donc hériter d’une ou de plusieurs interfaces de base et même d'une classe de base et d'une ou de plusieurs interfaces de base. Dans ce dernier cas, la classe de base doit figurer en premier dans la liste.

Donc, comment tout cela se présente-t-il dans la réalité ? Voici un exemple assez complet. Jetez un coup d'œil, essayez peut-être par vous-même, et lisez ensuite l'explication complète qui suit :

using System;
using System.Collections.Generic;

namespace Interfaces
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Dog> dogs = new List<Dog>();
            dogs.Add(new Dog("Fido"));
            dogs.Add(new Dog("Bob"));
            dogs.Add(new Dog("Adam"));
            dogs.Sort();
            foreach(Dog dog in dogs)
                Console.WriteLine(dog.Describe());
            Console.ReadKey();
        }
    }

    interface IAnimal
    {
        string Describe();

        string Name
        {
            get;
            set;
        }
    }

    class Dog : IAnimal, IComparable
    {
        private string name;

        public Dog(string name)
        {
            this.Name = name;
        }

        public string Describe()
        {
            return "Hello, I'm a dog and my name is " + this.Name;
        }

        public int CompareTo(object obj)
        {
            if(obj is IAnimal)
                return this.Name.CompareTo((obj as IAnimal).Name);
            return 0;
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}

Commençons par le milieu, où nous déclarons l'interface. Comme vous pouvez le constater, la seule différence par rapport à une déclaration de classe est le mot clef utilisé : interface au lieu de classe. De plus, le nom de l'interface est préfixé par un I pour interface. Il s'agit simplement d'une norme de codage et non d'une exigence. Vous pouvez appeler vos interfaces comme bon vous semble, mais, comme elles sont utilisées en tant que classes, vous pourriez avoir du mal à faire la différence entre classes et interfaces dans votre code, le préfixe I est plutôt logique.

Ensuite, toujours dans l'implémentation de l'interface, nous déclarons la méthode Describe, puis la propriété Name, qui comporte à la fois un mot-clef get et un mot-clef set, ce qui en fait une propriété en lecture et en écriture. Vous remarquerez également l'absence de modificateurs d'accès (public, private, protected, etc.), car ils ne sont pas autorisés dans une interface. Ils sont tous publics par défaut.

La prochaine étape est la déclaration de notre classe Dog. Notez que cela ressemble à un héritage de classe, avec un deux-points entre le nom de la classe dérivée Dog et la "classe" interface qui est mise en œuvre. Cependant, dans ce cas, deux interfaces sont implémentées pour la même classe, simplement séparées par une virgule (héritage multiple). Vous pouvez implémenter autant d'interfaces que vous le souhaitez, mais dans ce cas, nous n'en implémentons que deux: notre propre interface IAnimal et l'interface .NET IComparable, qui est une interface partagée pour les classes pouvant être triées. Comme vous pouvez le constater, nous avons implémenté à la fois la méthode et la propriété à partir de l'interface IAnimal, ainsi qu'une méthode CompareTo à partir de l'interface IComparable.

Vous pensez peut-être : si nous devons faire tout le travail nous-mêmes, en mettant en œuvre toutes les méthodes et propriétés d'une interface, pourquoi nous embêter ? Un très bon exemple du bénéfice en retour du temps investi est donné en haut de notre exemple. Ici, nous ajoutons une série d'objets Dog à une liste, puis nous trions la liste. Comment la liste sait-elle comment trier les chiens ? Parce que notre classe Dog a une méthode CompareTo qui permet de comparer deux chiens. Et comment la liste sait-elle que notre objet Dog peut faire exactement cela, et quelle méthode appeler pour faire comparer les chiens ? Parce que nous le lui avons dit, en implémentant une interface qui promet une méthode CompareTo ! C'est la vraie beauté des interfaces.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!