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
- prenom : String
+ identifie ( ) : String
+ getNom ( ) : String
+ getPrenom ( ) : String
Code c# (Personne.cs) (29 lignes)
public class Personne { private String nom; private String prenom; ///<summary> ///Constructeur ///</summary> ///<param name="nom">Nom de la personne</param> ///<param name="prenom">Prénom de la personne</param> public Personne(String nom, String prenom) { this.nom = nom; this.prenom = prenom; } ///<summary> ///Retourne le nom de la personne ///</summary> public String getNom() { return nom; } ///<summary> ///Retourne le prénom de la personne ///</summary> public String getPrenom() { return prenom; } }
Définition de la classe Lecteur
- emprunts : [ ] Livre
+ emprunte ( Livre livre ) : void
+ rapporte ( Livre livre ) : void
+ getEmprunts ( ) : [] Livre
Code c# (Lecteur.cs) (48 lignes)
public class Lecteur : Personne { private DateTime inscription; private ArrayList emprunts; ///<summary> ///Constructeur ///</summary> ///<param name="nom">Nom du lecteur</param> ///<param name="prenom">Prénom du lecteur</param> ///<param name="inscription">Date d'inscription</param> public Lecteur(String nom, String prenom, DateTime inscription) : base (nom, prenom) { this.inscription = inscription; } ///<summary> ///Retourne la liste des livres empruntés par ce lecteur en ce moment ///</summary> public ArrayList getEmprunts() { return emprunts; } ///<summary> ///Retourne la date d'inscription de ce lecteur ///</summary> public DateTime getInscription() { return inscription; } ///<summary> ///Ajoute un livre aux livres empruntés par ce lecteur en ce moment ///</summary> ///<param name="livre">Livre emprunté</param> public void emprunte(Livre livre) { emprunts.Add(livre); } ///<summary> ///Rapporte un livre à la bibliothèque ///Enlève donc le livre de ses livres empruntés en ce moment ///</summary> ///<param name="livre">Livre rapporté</param> public void rapporte(Livre livre) { emprunts.Remove(livre); } }
Que pouvons nous remarquer de particulier dans ce code ?Que pouvons nous remarquer de particulier dans ce code ?
Code c# (1 ligne)
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.
Code c# (6 lignes)
public Lecteur(String nom, String prenom, DateTime inscription) : base (nom, prenom) { this.inscription = inscription; }
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.
Nous pouvons tester ces classes en créant un petit programme en mode console.
Code c# (Lecteur.cs) (12 lignes)
class Program { static void Main(string[] args) { Console.WriteLine(pers.getPrenom() + " " + pers.getNom()); Console.WriteLine(lecteur.getPrenom() + " " + lecteur.getNom() + " " + lecteur.getInscription()); Console.WriteLine("\n\nPress any key to exit..."); Console.ReadKey(); } }
Ce programme affiche les lignes suivantes :
Bill Ballantine 21/12/2024 19:55:10
Press any key to exit...
_
English translation
You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.
Thank you in advance.
Document created the 15/10/2006, last modified the 07/04/2023
Source of the printed document:https://www.gaudry.be/en/csharp-heritage.html
The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.