Le but de cet article n’est pas de vous expliquer ce qu’est l’héritage de classe ou l’implémentation d’interface en c# .Net 2.0. Je vais ici vous donner un exemple concret d’utilisation.
Programmation > .Net
Recherche :   
Actualité Système Salon Concours Outils Programmation Devparadise Programmation HTML .Net JavaScript VBScript ASP PHP Visual Basic Perl Java Active X SQL XML WAP Delphi Graphisme Flash Web Design Promotion Référencement Publicité Valeur de votre site Outils Systèmes Windows Unix Linux Benchmark Hardware Réseaux locaux Droit Sécurité
Illustration de l’héritage de classe et de l’implémentation d’interface en c# .Net 2.0
  Auteur : Siegfried DUHAMEL

Le but de cet article n’est pas de vous expliquer ce qu’est l’héritage de classe ou l’implémentation d’interface en c# .Net 2.0. Je vais ici vous donner un exemple concret d’utilisation.

Publicité 
Imaginons que nous voulions créer une application permettant d'afficher des recettes de cuisine.
Je vous propose pour cela l'interface utilisateur suivante :

Dans lstBoxRecettes seront affichés les titres de nos recettes. Lorsque l'une d'entre elles sera sélectionnée les informations la concernant s'afficheront dans les différents contrôles situés en dessous.
La première information indiquera le type de recette, pour l'exemple prenons trois types :

  • Entrée ;
  • Plat ;
  • Dessert.
Le reste des informations sera commun à toutes les recettes.
Les ingrédients auront une information sur leur quantité qui se modifiera automatiquement si l'utilisateur change le nombre de personnes.
Pour illustrer mon propos j'ai choisi de faire :
  • une interface "IProportionnalite" ;
  • une classe abstraite "Recette" ;
  • trois classes "Entree", "Plat" et "Dessert" qui vont hériter de la classe "Recette" et implémenter "IProportionnalite" ;
  • et une classe "Ingredient".

Présentation des objets utilisés par la suite.

1 - L'interface "IProportionnalite"

Je la présente tout de suite mais nous reviendrons en détails dessus un peu plus tard. Elle se présente ainsi :

public interface IProportionnalite
{
   event EventHandler ModificationProportionTerminee;
   void ModifierProportion(int _nProportionFinale);
}

Elle nous servira par la suite pour contrôler les calculs de proportion lorsque nous modifierons le nombre de personnes pour lesquelles nous voulons préparer notre "Recette".

2 - La classe abstraite "Recette"

Voici sa déclaration :

public abstract class Recette : IProportionnalite

Toute de suite nous entrons dans le vif du sujet : le fait que cette classe soit abstraite indique qu'elle est faite pour être dérivée car elle ne pourra pas être instanciée. Vous ne pourrez donc pas faire la chose suivante :

Recette r = new Recette();

Car le compilateur vous répondra :

Impossible de créer une instance de la classe abstraite ou de l'interface 'HeritageImplementation.Recette'

Nous allons devoir l'utiliser autrement : créer une ou des classes qui vont en hériter. Par contre cela ne nous empêche pas d'ajouter des propriétés, des méthodes, des variables, etc… dans "Recette".
Quel est l'intérêt ? Par exemple, la propriété :

public string MonNomRecette
{
   get { return monNomRecette; }
}

Sera commune à toutes les classes héritants de "Recette". Nous n'aurons pas besoin de la réécrire dans chacune d'elles.

3 - Les classes "Entree", "Plat" et "Dessert"

Elles héritent de "Recette" et implémentent l'interface "IProportionnalite" :

public class Dessert : Recette, IProportionnalite

Toutes leurs propriétés sont définies dans la classe dont elles héritent. Leur constructeur permet de renseigner les différentes propriétés de la classe. Nous trouvons aussi la définition, propre à chacune d'elle, de la méthode "ModifierProportion" et de "l'EventHandler ModificationProportionTerminee" provenant de l'interface "IProportionnalite".

4 - La classe "Ingredient"

Pas grand-chose à ajouter, c'est une classe toute simple.

Utilisation dans notre windows form.

1 - Une liste d'objets "Recette"

private List<Recette> maListeDeRecettes = null;

J'ai utilisé ici l'une des collections génériques du .NET Framework 2.0, qui permet de typer ce qu'elle contient. Je ne peux donc y ajouter que des objets du type annoncé, ici "Recette". Pour plus de détail voir les collections génériques (http://msdn2.microsoft.com/fr-fr/library/system.collections.generic.aspx) ou encore pourquoi utiliser les génériques (http://msdn2.microsoft.com/fr-fr/library/bb727324.aspx).

2 - Un constructeur

public Form1()

J'y appelle la méthode qui va créer ma liste de "Recette". Je remplis ensuite lstBoxRecettes. Voici la première illustration du thème abordé dans cet article : je fais un foreach sur des objets "Recette" sans me préoccuper d'autre chose. Normal, j'ai une liste générique qui contient des objets "Recette", pourtant vous allez voir par la suite que je n'ai pas remplis cette liste directement avec ces objets…

3 - Puis quelques méthodes et évènements

private void CreerListeRecettes()

Pour faire simple, c'est ici que je crée ma liste de recettes. Pour l'exemple j'ai ajouté, en dur dans le code, 3 recettes, une pour chaque type. Vous pouvez voir ici que pour chaque type j'ai créé une méthode d'ajout particulière pour plus de clarté :

   private void AjoutEntree
   private void AjoutPlat
   private void AjoutDessert

Regardons "AjoutEntree" (les deux autres sont sur le même modèle) :

Je contrôle juste que ma liste d'objets "Recette" est instanciée avec :

private void InstanciationListeRecettes()

Je crée un objet "Entree" que j'ajoute ensuite dans ma liste d'objets "Recette" (maListeDeRecettes.Add(monEntree);) !
Pourtant cette liste est typée et n'accepte que des objets "Recette" !
En fait, grâce à l'héritage, notre objet "Entree", comme les objets "Plat" et "Dessert", est aussi un objet "Recette". De ce fait, lors du remplissage de lstBoxRecettes, je peux faire un foreach (qui fait un cast des objets itérés - http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/csref/html/vclrfTheForeachStatement.asp) sans m'occuper du type réel de l'objet.

Remarque : j'utilise là encore une liste générique pour les ingrédients et une autre collection apparue dans le .NET Framework 2.0 : une StringCollection (http://msdn2.microsoft.com/fr-fr/library/system.collections.specialized.stringcollection.aspx).

private void lstBoxRecettes_SelectedIndexChanged(object sender, EventArgs e)

Dans cet évènement je gère l'affichage des informations concernant l'objet sélectionné dans lstBoxRecettes.
Avec ce que nous venons de voir nous pourrions nous attendre à obtenir pour lstBoxRecettes.SelectedItem.GetType().Name la valeur "Recette". Voyons le résultat :

  • La sélection

  • Le résultat

    C'est bien "Entree" qui s'affiche, le type de notre objet. Nous pourrions donc imaginer un système de classement sur le type de l'objet, ou encore un système de filtre.

    private void nudPersonnes_ValueChanged(object sender, EventArgs e)

    A partir d'ici abandonnons l'illustration de l'héritage. C'est l'implémentation de l'interface qui va être mis en avant. Nous avons vu plus haut que nos objets "Entree", "Plat" et "Dessert" implémentent l'interface "IProportionnalite". Lorsque l'utilisateur modifie le nombre de personnes ici :

    Je tente de caster la sélection dans lstBoxRecettes en "IProportionnalite" (le mot clef as donne permet d'obtenir null si le cast est impossible). Si tout va bien :

      if (monIConvertion != null)
      {
        monIConvertion.ModificationProportionTerminee += new EventHandler(monIConvertion_ModificationTerminee);
        monIConvertion.ModifierProportion((int)nudPersonnes.Value);
      }
    Je m'abonne à mon évènement pour savoir quand mes calculs sont terminés et je passe mon nouveau nombre de personnes à la méthode chargée de faire les calculs :

    void ModifierProportion(int _nProportionFinale);

    Cette méthode étant implémentée dans les classes "Entree", "Plate" et "Dessert", chacune d'elle peut ainsi avoir sa propre règle de calcul.

    private void monIConvertion_ModificationTerminee(object sender, EventArgs e)

    Une fois mes calculs terminés, je peux remplir ma liste d'ingrédients avec les nouvelles valeurs en utilisant cette fois un cast vers l'objet "Recette" pour récupérer ma liste d'ingrédients.

    Vous avez pu voir que dans le code de Form1, je n'ai utilisé les classes "Entree", "Plat" et "Dessert" qu'au moment de leur création pour l'ajout dans la liste générique de "Recette".
    Par la suite je n'ai utilisé, pour les traitements d'affichage, que les types "Recette" et "IProportionnalite". L'héritage m'a donc permis de faire abstraction des types d'objets particuliers tant que je n'en ai pas besoin. Dans un livre de recettes, on utilise bien des recettes en général. Quand à l'interface, je pourrais aussi bien l'utiliser pour d'autres choses que des recettes s'ils ont besoin d'un calcul de proportion. J'ai donc illustré, au-delà de l'héritage et de l'implémentation, la notion plus large de polymorphisme (http://msdn2.microsoft.com/fr-fr/library/z165t2xk.aspx).

  • A lire aussi sur Devparadise.com :
  • Message de confirmation sur un DataGrid via le code Behind
  • Comment ouvrir un pop-up après validation d’un formulaire par les contrôles d...
  • Installation de SQL Server 2008
  • La sérialisation (Marshaling) en XML en C# .Net 2.0
  • Rôle et Fonctionnalités sous Windows Server 2008
  • A télécharger aussi sur Devparadise.com :
  • SOURCE : Message de confirmation sur un DataGrid via le code Behind
  • Comment ouvrir un pop-up après validation d’un formulaire par les contrôles d...
  • SOURCES : Création en VB6 d'une DLL ActiveX utilisant GDI+, et appel de cette...
  • Source de l'article sur l’héritage de classe et de l’implémentation
  • Code Source : sérialisation (Marshaling) en C# .Net 2.0

  • © 1997-2009 tous droits réservés Devparadise.com
    Les logos, et marques déposées sont la propriété de leurs détenteurs respectifs.
    Devparadise.com s'est engagé à respecter la confidentialité des données personnelles régies par la loi 78-17 du 6 janvier 1978.
    Déclaration C.N.I.L. n° 621623
    dotnet,c#,csharp,framework,2,.net,héritage,heritage,implémentation,implemantation,interface