Objectifs : Comprendre la notion d’interface, d’une classe abstraite et celle de l’héritage.
Dans les autres tutos on a vu à quoi correspond une classe java concrète, cette fois, à travers ce tutoriel nous allons découvrir d’autres types de classes, voir la classe abstrait et l’interface ainsi que le mécanisme d’héritage de chaque type.
1. Une classe abstraite :
Une classe abstraite est une classe qui a la même structure qu’une classe normale mais qui peut en plus contenir des méthodes abstraites.
Rappel: une méthode abstraite est une méthode déclarée mais pas définie, elle n’a pas de corps.
Structure :
abstract class Nom_class
{
//on peut ajouter des attributs ;
abstractType_Retour Nom_Methode_Ab() ;
// on peut ajouter d’autres classes abstraites ou concrètes.
}
Comme une classe concrète, une classe abstraite peut avoir un constructeur mais on ne
pourra jamais construire une instance d’une classe abstraite, (ce constructeur sera utilisé par l’héritage).
Remarque : Il suffit d’englober une seule méthode abstraite pour que la classe soit considérée abstraite et doit être déclarée ainsi.
2. Les interfaces :
Une interface est une classe abstraite mais qui ne peut contenir que des méthodes abstraites (pas de méthodes concrètes).
Structure :
interface class Nom_Interface
{
//on peut ajouter des attributs ;
Type_Retour Nom_Methode_Ab() ;
}
Remarque : Toutes les méthodes des interfaces sont par défaut public, static et abstract donc l’ajout ou non de ces mots clés ne change rien.
Leurs attributs sont par défaut public et doivent être déclarés final.
Par contre la modification d’une de ces propriétés déclenche une erreur de compilation.
L’héritage consiste à faire transmettre des propriétés (attributs et méthodes) d’une mère (classe concrète, classe abstraite ou interface) à des classes filles (classe concrète, classe abstraite ou interface).
La relation d’héritage exprime une relation de Is a (est un) entre la classe fille est la classe mère.
Remarque : L’héritage multiple est interdit par java ! Une même classe ne peut hériter qu’au plus d’une seule classe.
Supposons qu’on a redéfinie une méthode et qu’on souhaite quand même dans celle-ci faire appel à la méthode héritée, pour le faire java a réservé le mot clé super, on va continuer avec notre exemple :
Remarque : ni super ni this ne peuvent figurer dans une méthode statique.
Super ne peut pas être utilisé avec une méthode statique, donc la solution est de l’appeler précédée par le nom de la classe, comme suit :
Donc pour essayer avec le super, on va éliminer le static des méthodes Pointage dans les 2 classes pour que ça donne :
Donc comme le montre le résultat, super permet d’appeler la méthode héritée seulement si cette dernière n’est pas statique.
Remarque : de même pour les attributs si la classe mère et la classe filles possède chacune un attribut qui tous deux portent le nom, donc pour faire la différence on utilise this et super comme suit :
this.CIN = « »;
super.CIN = « » ;
a. Appel aux constructeurs de la classe mère :
Le constructeur de la sous-classe doit implicitement ou explicitement faire appel au constructeur de la super classe pour justifier la relation Is a. Donc si la classe mère admet un constructeur par défaut ou un constructeur vide, dans ce cas il sera appelé implicitement sinon si cette dernière admet que des constructeurs paramétrés, donc obligatoirement dans la classe fille au minimum un constructeur doit être construit dans lequel un appel explicite au constructeur paramétré de la classe mère, voyons ensemble un exemple :
On a ajouté un constructeur paramétré dans la classe Employe ce qui a déclenché une erreur dans la classe Technicien, pour corriger ça on doit y ajouter un constructeur paramétré ou pas qui fait appel au constructeur paramétré de la classe Employe :
Remarque :
On va faire un essai pour voir laquelle des méthodes sera appelée, la méthode de la classe mère ou bien celle redéfinie par la sous-classe :
On a changé la valeur de retour false par true, la méthode pointage dans la classe Technicien puis dans la méthode main (point d’entrée de l’exécution) on a déclaré une variable t de type Technicien à laquelle on lui a référencé une instance de type Technicien aussi comme le montre la figure.
Après l’exécution le résultat sera comme suit :
On remarque bien que la méthode redéfinie qui a été appelée.
On va faire une petite modification et voir s’il y aura du changement au niveau du résultat :
Comme vous voyez j’ai juste modifié le type de la variable t, voyons donc le résultat :
Le résultat a changé, cette fois c’est la méthode de la classe Employe qui a été exécutée.
Explication :
Classe_mére c = new Classe_fille ;
c.Method() ;
▶ Erreur de compilation : car une référence ne peut pas appelée une méthode non existante dans sa classe.
Remarque : Si la classe fille contient une méthode non déclarée ni définie dans la classe mère et que la référence de l’instance est de type super classe comme l’exemple qu’on vient de voir, dans ce cas le compilateur réclame une erreur :
b. Héritage des attributs :
On va comprendre ça à l’aide d’un bout de code :
On a ajouté un attribut à la classe Employe comme suit :
final String Immat_Societe= « 12345678 » ;
L’exécution de ce code donnera :
On peut constater que les sous classes héritent de la super classe tous les attributs et leurs valeurs, et une modification sur la valeur d’un attribut dans la classe fille n’engendre pas une modification sur le même attribut de la classe mère sauf s’il s’agit d’un attribut déclaré static.
Nous allons voir un exemple avec une classe concrète pour bien comprendre ce que je viens d’expliquer :
J’ai marqué les références par des couleurs :
On va déclarer différentes variables, modifier les valeurs des variables et voir son impact sur les attributs des autres variables :
Résultat de l’exécution :
Toutes ces instructions nous ont permis de remarquer que la valeur de l’attribut Type ne change que pour la copie de l’instance qu’il a modifié (c.Type= »chat ») sinon chacune des autres instances quelle que soit la classe de la référence ont gardé leur valeurs initiales (null) avant de les modifier et après avoir modifié celle d’une autre instance.
Remarque : Pour chaque instance des classes filles on trouve que la valeur de chaque attribut Type est null pas dû à l’affectation des valeurs par défauts mais suite à l’héritage des valeurs des attributs de la classe mère.
Par contre l’attribut Nbr_Animal chaque modification faite par l’une des instances créées (Animal, Chat, Poisson) est appliquée sur une même copie partagée entre elles car cet attribut est déclaré static.
Rappel : Les attributs et les méthodes dépendent en premier lieu du type de la référence et non du réfèrent.
Remarque : On prend :
Classe_Mere a=new Classe_Fille() ;
a.Method() ;
Sachant que la Method() est une méthode déjà implémentée dans la classe mère :
Si la classe mère ne contient pas la méthode Method(), une erreur de compilation s’affiche.
Si la classe mère contient la méthode Method() et la classe fille l’a redéfinie alors la méthode redéfinie sera appelée.
Si la classe mère contient la méthode Method() et la classe fille ne l’a pas redéfinie alors la méthode héritée sera appelée.
c. La conversion (casting) :
Classe_Mere a= new Classe_Fille() ;
Une telle affectation est autorisée par le compilateur et c’est lui qui fait la conversion implicitement.
Dans le cas où la classe mère est une classe abstraite :
Classe_Fille a= new Classe_Mere() ;
▶ Erreur de compilation !!!
Prenons l’exemple de tout à l’heure :
Une affectation directe sans conversion d’une classe mère à une classe fille n’est pas autorisée, c’est la conversion forcée qui doit intervenir :
Donc après la conversion on peut afficher l’attribut Type pour que ça donne :
Oups !! Ce n’est pas le résultat attendu !! Java nous dit que la conversion d’Animal en Chat n’est pas possible!
En fait, on ne peut pas affecter une instance de la classe mère à une référence de la classe fille. La conversion forcée marche dans un seul cas :
Après la conversion explicite ça donne :
Une conversion forcée n’est acceptée que si l’instance est une instance de la classe fille, référencée par une variable de la classe mère
Une modification sur x ou w engendre une modification sur l’autre référence (w ou x) comme on le voit pour l’attribut Type car les 2 références pointent sur la même instance.
▶ L’héritage d’une interface :
Pareil pour les interfaces, une classe peut implémenter une interface mais pas le contraire, comme une interface peut hériter d’une autre interface.
Pour qu’une classe implémente une interface on utilise le mot clé implements.
Une interface peut hériter d’un nombre quelconque d’interfaces.
Pour qu’une interface hérite d’une autre interface, on utilise le mot clé extends.
Une classe peut implémenter un nombre quelconque d’interfaces.
Une classe peut en même temps hériter d’une classe et implémenter des interfaces :
Classe_Fille extends Classe_Mere implements Interface1, Interface2,…,InterfaceN
De même quand une classe implémente des interfaces elle doit redéfinir (implémenter) toutes les méthodes figurant dans toutes les interfaces (toute méthode d’une interfaces est abstraite) sinon la classe sera considérée comme une classe abstraite et doit être déclarée ainsi (avec le mot clé abstract).
Concrétisons l’exemple des maladies :
Les méthodes héritées doivent être redéfinies tant que la classe n’est pas abstraite.
Tout attribut doit être déclaré final, ce qui fait que toute classe ou interface qui implémente ou hérite cette interface ne peut pas modifier la valeur des attributs hérités.
Une interface ne peut pas être instanciée :
Interface_T= new Interface_T() ; ==> erreur de compilation
Elle peut seulement être une référence :
Interface_T = new Interface_T ;
Le tuto est terminé enfin ! C’était un peu long car ce chapitre est un peu délicat, contenant plusieurs détails auxquels il faudra bien faire attention.
Normalement on a tout vu de ce qui est une classe abstraite, qu’est-ce que c’est qu’une interface, la notion d’héritage et toutes ses règles.
Rendez-vous avec le prochain tutoriel qui sera réservé pour les boucles et les structures conditionnelles.
Merci de nous avoir fait confiance.
Je vous invite à consulter quotidiennement le site d’Odellya pour profiter des prochains tutoriels qui seront bientôt à votre disposition.