L'héritage en C#

« C'est quoi hériter? »

Si tu te poses cette question, je pense qu'il serait bon de consulter préalablement les pages du chapitre "Programmer", et plus précisément les notions d'orienté objet, d'héritage, et de polymorphisme.

Dans le framework .NET, nous emploierons peu le terme de superclasse au profit de classe de base.

Comme les structures ne participent pas au mécanisme d'héritage, nos classes ne pourront pas hériter d'une structure, mais seulement d'une autre classe (et toutes les classes héritent en fait de la classe Object).

Héritage multiple en C#

Comme dans d'autres langages (par exemple Java), C# ne nous permet pas d'héritage multiple. En effet, en C++ nous pouvions créer une classe qui hérite de plusieurs classes parentes, mais cette méthode peut se révéler dangereuse si nous ne maîtrisons pas totalement notre arborescence.

Nous pouvons tout de même hériter de plusieurs classes, dans la mesure ou nous remontons l'arborescence, mais ce n'est pas de l'héritage multiple car chaque classe n'hérite que d'un seul parent direct.
Par exemple, la classe C hérite de la classe B qui hérite elle même de la classe A.

Nous pouvons substituer utiliser l'implémentation de plusieurs interfaces comme substitut del'héritage multiple, mais nous verrons ceci plus tard.

Exemple d'héritage

Pour notre exemple, nous pouvons reprendre les classes Personne et Lecteur que nous avons utilisé pour expliquer l'héritage en Java.

Définition de la classe Personne

Personne
- nom : String
- prenom : String
+ Personne ( String nom , String nom )
+ identifie ( ) : String
+ getNom ( ) : String
+ getPrenom ( ) : String
  1. public class Personne
  2. {
  3. private String nom;
  4. private String prenom;
  5. ///<summary>
  6. ///Constructeur
  7. ///</summary>
  8. ///<param name="nom">Nom de la personne</param>
  9. ///<param name="prenom">Prénom de la personne</param>
  10. public Personne(String nom, String prenom)
  11. {
  12. this.nom = nom;
  13. this.prenom = prenom;
  14. }
  15. ///<summary>
  16. ///Retourne le nom de la personne
  17. ///</summary>
  18. public String getNom()
  19. {
  20. return nom;
  21. }
  22. ///<summary>
  23. ///Retourne le prénom de la personne
  24. ///</summary>
  25. public String getPrenom()
  26. {
  27. return prenom;
  28. }
  29. }

Définition de la classe Lecteur

Lecteur
- inscription : DateTime
- emprunts : [ ] Livre
+ Lecteur ( String nom, String prenom, DateTime inscription )
+ emprunte ( Livre livre ) : void
+ rapporte ( Livre livre ) : void
+ getEmprunts ( ) : [] Livre
  1. public class Lecteur : Personne
  2. {
  3. private DateTime inscription;
  4. private ArrayList emprunts;
  5. ///<summary>
  6. ///Constructeur
  7. ///</summary>
  8. ///<param name="nom">Nom du lecteur</param>
  9. ///<param name="prenom">Prénom du lecteur</param>
  10. ///<param name="inscription">Date d'inscription</param>
  11. public Lecteur(String nom, String prenom, DateTime inscription)
  12. : base (nom, prenom)
  13. {
  14. this.inscription = inscription;
  15. this.emprunts = new ArrayList();
  16. }
  17. ///<summary>
  18. ///Retourne la liste des livres empruntés par ce lecteur en ce moment
  19. ///</summary>
  20. public ArrayList getEmprunts()
  21. {
  22. return emprunts;
  23. }
  24. ///<summary>
  25. ///Retourne la date d'inscription de ce lecteur
  26. ///</summary>
  27. public DateTime getInscription()
  28. {
  29. return inscription;
  30. }
  31. ///<summary>
  32. ///Ajoute un livre aux livres empruntés par ce lecteur en ce moment
  33. ///</summary>
  34. ///<param name="livre">Livre emprunté</param>
  35. public void emprunte(Livre livre)
  36. {
  37. emprunts.Add(livre);
  38. }
  39. ///<summary>
  40. ///Rapporte un livre à la bibliothèque
  41. ///Enlève donc le livre de ses livres empruntés en ce moment
  42. ///</summary>
  43. ///<param name="livre">Livre rapporté</param>
  44. public void rapporte(Livre livre)
  45. {
  46. emprunts.Remove(livre);
  47. }
  48. }

Que pouvons nous remarquer de particulier dans ce code ?Que pouvons nous remarquer de particulier dans ce code ?

  1. public class Lecteur : Personne

Nous avons utilisé l'opérateur : qui signifie que la classe Lecteur est une sous classe (ou classe dérivée) de Personne.

  1. public Lecteur(String nom, String prenom, DateTime inscription)
  2. : base (nom, prenom)
  3. {
  4. this.inscription = inscription;
  5. this.emprunts = new ArrayList();
  6. }

Dans notre constructeur, nous recevons un nom et un prénom définissant la personne. Nous n'avons défini ces variables nulle-part dans le code de la classe Lecteur, ce sont donc des propriétés que l'objet de type Lecteur hérite de la classe Personne.

Pour cette raison, afin d'éviter toute confusion possible, nous utilisons le constructeur de la classe de base (Personne) pour instancier ces valeurs.

  • Nous pouvons remarquer que l'appel au constructeur de la super classe se fait à l'aide de l'opérateur :.
  • Si le constructeur de la sous-classe n'appelle pas explicitement le constructeur de la classe de base, c'est le constructeur par défaut de cette dernière qui est invoqué.
  • Si, comme dans ce cas, nous n'avons pas de constructeur sans argument pour la classe de base, nous devons impérativement faire appel au constructeur paramétré de la classe de base dans la déclaration de notre sous classe. Si nous ne désirons pas utiliser le mot clé base pour notre constructeur de notre classe Lecteur, nous devons ajouter un constructeur sans argument à notre classe Personne.

La date d'inscription est une des caractéristiques de notre Lecteur, nous pouvons directement affecter la valeur de la date d'inscription à la variable inscription au moment de l'appel au constructeur de Lecteur, car nous considérons qu'un lecteur n'existe qu'à partir du moment où il est inscrit dans la bibliothèque. Nous pouvons remarquer ici l'emploi du mot clé this qui désigne la classe elle-même.

Table des matières Haut

Nous pouvons tester ces classes en créant un petit programme en mode console.

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. Personne pers = new Personne("Morane", "Bob");
  6. Lecteur lecteur = new Lecteur("Ballantine", "Bill", DateTime.Today);
  7. Console.WriteLine(pers.getPrenom() + " " + pers.getNom());
  8. Console.WriteLine(lecteur.getPrenom() + " " + lecteur.getNom() + " " + lecteur.getInscription());
  9. Console.WriteLine("\n\nPress any key to exit...");
  10. Console.ReadKey();
  11. }
  12. }

Ce programme affiche les lignes suivantes :

Bob Morane
Bill Ballantine 21/11/2024 09:50:57

Press any key to exit...
_

Version en cache

21/11/2024 09:50:57 Cette version de la page est en cache (à la date du 21/11/2024 09:50:57) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.

Document créé le 15/10/2006, dernière modification le 07/04/2023
Source du document imprimé : https://www.gaudry.be/csharp-heritage.html

L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.