Notion d'héritage en "orienté-objet"
Hériter... dans la vie, et en programmation
Nous héritons tous à notre naissance d'une partie du patrimoine génétique de nos parents. Malgré celà, nous développons nos propres caractéristiques en plus de celles dont nous héritons. Le principe est identique en orienté objet.
Nous pouvons par exemple définir une classe Personne.
Tous les objets issus de la classe Personne possèdent un nom et un prénom. Ce sont certains de leurs attributs.
Nous allons fournir à tous les objets de la classe Personne une méthode identifie() qui nous retourne le prénom suivi du nom de la personne.
Nous allons à présent gérer les personnes qui sont inscrites dans une bibliothèque. Ces lecteurs sont avant tout des personnes, et présentent donc toutes les caractéristiques de la classe Personne.
Mais les lecteurs possèdent tous certaines qualités (des attributs) communes (la date d'inscription, les livres empruntés) que ne possèdent pas toutes les personnes.
Nous pouvons créer une classe Lecteur, qui hérite des propriétés et des méthodes de la classe Personne, mais qui implémente des méthodes qui ne s'appliquent par exemple qu'à des personnes inscrites dans la bibliothèque. Nous remarquons de suite le gain de temps et d'espace, car nous ne sommes plus obligés de définir les méthodes et attributs qui sont déjà définis dans la classe Personne. Nous ne devons plus définir que ce qui différe de la classe dont nous héritons.
Les classes peuvent donc se présenter comme une arborescence, la racine étant en haut.
Nous dirons de la classe Personne qu'il s'agit d'une super classe, et de la classe Lecteur, qu'il s'agit d'une sous classe.
Remarques à propos de l'héritage
Héritage multiple
Dans certains langages tels que le C++, nous pouvons retrouver un objet qui hérite de plusieurs parents (héritage multiple), mais dans d'autres comme en Java nous ne retrouverons que des objets qui n'héritent que d'un parent maximum.
Mais plusieurs sous classes peuvent hériter d'une même super classe, il ne s'agit pas la d'héritage multiple puisque chaque sous classe n'hérite que d'une classe.
Héritage par défaut
Chaque classe en Java ne peut posséder qu'une super classe, mais elle peut avoir un nombre illimité de sous classes. Toute super classe ou sous classe que nous créons hérite automatiquement de la classe Object (la super super classe). Les attributs et les propriétés de la classe Object sont donc accessibles.
Généraliser - Spécialiser
Le plus souvent, lorsque nous effectuons un déplacement vers le haut (vers la super classe), nous généralisons. En effet, plus la classe est proche de la super classe, moins elle possède de méthodes et d'attributs spécifiques. Comme nous groupons les éléments communs dans une super-classe, nous pouvons parler de factorisation de ces éléments. Une généralisation nous permet une certaine abstraction car tout objet d'une sous-classe peut-être considéré comme un objet de sa classe parent1.
Le corollaire de cette affirmation est que plus nous nous éloignons de la super classe (plus nous descendons dans la structure), plus nous remarquons une spécialisation des classes.
L'héritage en Java
Définition de la classe Personne
- prenom : String
+ identifie ( ) : String
+ getNom ( ) : String
+ getPrenom ( ) : String
Code Java (25 lignes)
public class Personne { /** * constructeur * @param nom * @param prenom */ this.nom = nom; this.prenom = prenom; } /** * @return donne le nom. */ return nom; } /** * @return donne le prenom. */ return prenom; } }
Définition de la classe Lecteur
- emprunts : [ ] Livre
+ emprunte ( Livre livre ) : void
+ rapporte ( Livre livre ) : void
+ getEmprunts ( ) : [] Livre
Code Java (41 lignes)
import java.util.ArrayList; import java.util.Date; public class Lecteur extends Personne { /** * Constructeur * @param nom * @param prenom * @param inscription */ super(nom, prenom); this.inscription = inscription; } /** * * @return donne la liste des livres empruntés en ce moment */ return emprunts; } return inscription; } /** * Ajoute le livre à ses livres empruntés en ce moment * @param livre */ public void emprunte(Livre livre){ emprunts.add(livre); } /** * Rapporte un livre à la bibliothèque * Enlève donc le livre de ses livres empruntés en ce moment * @param livre */ public void rapporte(Livre livre){ emprunts.remove(livre); } }
Que pouvons nous remarquer de particulier dans ce code ?
Code Java (1 ligne)
public class Lecteur extends Personne
Nous avons utilisé le mot réservé extends qui signifie que la classe Lecteur est une (ou classe dérivée) de Personne.
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 super classe (Personne) pour instancier ces valeurs.
- Nous pouvons remarquer que l'appel au constructeur de la super classe se fait à l'aide du mot réservé super.
- Si le constructeur de la sous-classe n'appelle pas explicitement le constructeur de la superclasse, c'est le constructeur par défaut de cette dernière qui est invoqué.
- Dans notre constructeur de sous-classe, l'invocation du constructeur de la superclasse doit être la première instruction. Aucune instruction ne peut se placer dans un constructeur avant l'appel du super constructeur.
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.
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 17/04/2005, last modified the 07/03/2020
Source of the printed document:https://www.gaudry.be/en/en/oriente-objet-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.
- ↑ Abstraction et héritage : Une page spécifique est consacrée à l'héritage vu comme une abstraction, et à la substitution selon B. Liskov : https://www.gaudry.be/en/oriente-objet-principe-substitution.html.
- ↑ Unified Modeling Language : corresponds to « langage de modélisation unifié » en français