Concept d’héritage
Féminin Masculin Redondant
-code: int -code: int
-nom:String -nom:String
-prénom:String -prénom:String Spécifique
-date:Date -date:Date
-email:Email -email:Email
-Epoux: Masculin -Epouse:Feminin
+getCode():int +getCode():int
………….. …………..
+getEpoux():iMasculin +getEpouse():Féminin
+setEpoux(….):void +setEpouse(….):void
Concept d’héritage
Factoriser
Masculin
Créer une
Féminin
-code: int -code: int
troisième classe
-nom:String -nom:String
-prénom:String -prénom:String Spécifique
-date:Date -date:Date
-email:Email -email:Email
-Epoux: Masculin -Epouse:Feminin
+getCode():int +getCode():int
………….. …………..
+getEpoux():iMasculin +getEpouse():Féminin
+setEpoux(….):void +setEpouse(….):void
Concept d’héritage
Personne
-code:int
…..
-email:Email
Factorisation
+getCode():int (membres
…….. communs)
………
Héritage
Féminin Masculin
-Epouse:Féminin
-Epoux: Masculin Membres
Spécifiques
+getEpoux():Masculin +getEpouse():Féminin
+setEpoux(…):void +setEpouse(….):void
Concept d’héritage
L’héritage est le second concept de la programmation orientée objets.
Le terme héritage exprime le principe selon lequel une classe peut hériter des
caractéristiques (attributs et méthodes) d’autres classes.
Elle consiste de créer de nouvelles classes à partir d’une classe existante,
les classes nouvellement définies sont considérées des sous types de la
classe d’origine.
L’héritage est exprimé à l’aide du mot réservé « extends ».
Un objet de type Personne est caractérisé par:…….
Un objet de type Masculin est caractérisé par: …….
Un objet de type Féminin est caractérisé par:…….
Concept d’héritage
Personne
-code:int
Classe mère ou
…..
Classe base ou -email:Email
Super classe
+getCode():int
……..
………
Féminin Masculin
Classe fille ou -Epouse:Feminin
Classe dérivée -Epoux: Masculin
ou +getEpoux(): +getEpouse():iFéminin
Sous classe Masculin +setEpouse(…):void
+setEpoux(….):void
Héritage
Personne
-code:int
…..
-email:Email
Spécialisation +getCode():int Généralisation
……..
………
Féminin Masculin
-Epouse:Feminin
-Epoux: Masculin
+getEpoux():Masculin +getEpouse():Féminin
+setEpoux(….):void +setEpouse(….):void
Arbre d’héritage
Classe Object
Chaque objet a le type de sa
Classe Figure classe et ceux ses classes
Classe Transport ascendantes.
Classe Animal Il n’ a pas les types de ses
classes descendantes
Classe TAérien Classe TMarin
Classe TTerrestre
Classe Avion Classe Hélicoptère
Avion avion=new Avion (‘’ Airbus ’’, C123);
avion a les types: Avion, TAérien, Transport et Object
Membres d’un objet d’une classe fille
Les membres d’un objet de la classe fille sont les membres
définies dans sa classe et les membres de toutes ses supers
classe jusqu’à la classe Objet. Ainsi, de point de vu espace
mémoire d’un objet de la classe dérivée, un espace est réservé
pour chaque attribut propre à la classe fille puis un espace
pour chaque attribut de toutes les classes qui lui sont
ascendantes.
Une classe dérivée possède toutes les méthodes définies
dans son corps et toutes les méthodes (sauf les constructeurs)
de toutes ses super classes jusqu’à la classe Object.
Redéfinition des méthodes
Une classe fille peut:
Utiliser intégralement
Utiliser partiellement le Utiliser un code
une méthode
code d’une méthode de sa nouveau.
de sa classe mère.
classe mère.
Redéfinition Définition
Héritage des des méthodes fraiche des
méthodes méthodes
Redéfinition des méthodes
La redéfinition (overriding) est la possibilité
d’utiliser exactement la même signature pour
définir un service dans un type et dans un sous
type (entre une classe et sa classe dérivée
directement ou indirectement).
Le type de retour du service doit être le même,
mais la visibilité peut changer ( mais doit être
>= visibilité initiale). On dit dans ce cas que la
classe fille a spécialisé la méthode.
Redéfinition des méthodes
Même signature
puclic class Mere{ Visibilité
supérieure
Cas de redéfinition
void f() {s.o.p(«Je suis f de la
mère »;}
}
puclic class Fille extends Mere{
public void f() {s.o.p(«Je suis f
de la fille »;}
}
Redéfinition des méthodes
Erreur:
puclic class Mere{ visibilité
inférieure
public void f() {s.o.p(«Je suis le
f de la mère »;}
}
puclic class Fille extends Mere{
void f() {s.o.p(«Je suis le f de
la fille »;}
}
Différence entre surcharge et Redéfinition
cas de
puclic class Mere{ Surcharge et
non
void f() {s.o.p(«Je suis le f de la redéfinition
mère »;}
}
puclic class Fille extends Mere{
void f(int x) {s.o.p(«Je suis le f
de la fille »;}
}
Instance this et super
Chaque instance d’une classe dérivée est munie de deux
références particulières :
this réfère l’instance elle-même.
super réfère la partie héritée de l’instance.
L’utilisation de l’un de ses mots clés est nécessaire quand on doit
distinguer entre deux membres qui portent le même nom et se
trouve dans plus d’une classe dans la hiérarchie de la dérivation.
Instance this et super
La référence this associé à un membre ( exp
this.m où m est un membre) permet de
désigner le membre le plus proche à partir
de la classe fille jusqu’à la classe Object.
La référence super associé à un membre
permet de désigner le membre le plus
proche à partir de la mère jusqu’à Object.
Instances this et Super
public class A {
int x=1, y=-1, w=-11;
}
class B extends A {
int x=2, y=-2, z=-22;
}
class C extends B {
int x=3, h=-3; public void f2(){
public void f1(){ System.out.println(super.x);
System.out.println(this.x); System.out.println(super.h);
System.out.println(this.h); System.out.println(super.y);
System.out.println(this.y); System.out.println(super.z);
System.out.println(this.z); }
} } }
Redéfinition de la méthode afficher
de la classe Point
class PointEspace extends Point{
private double x, y,z……….
public void afficher() {
super.afficher(); System.out.print( ‘’, ‘’
+ z;)
}
On définit dans la classe point la méthode symetrie comme suit
public Point symetrie() {
return new Point(-x,-y) ;}
Cette methode peut être redéfinie dans la classe PointEspace
comme suit : ( covariance)
public PointEspace symatrie(){
return new PointEspace(-getX(),-getY(),-z) ;}
Malgré que les deux signatures sont différentes
mais ça correspond à une redéfinition car PointEspace est un
sous type de Point.
•Remarque :
Il est conseillé de rajouter l’annotation @Override
avant toute méthode redéfinie, ceci est utile
pour que le compilateur réalise le contrôle et envoie
une erreur si la méthode ne redéfinie aucune autre méthode.
Mot clé final
Si une classe est précédée par le mot clé final,
elle ne peut être dérivée.
Elle est considérée obligatoirement comme feuille
dans la hiérarchie de l’héritage.
Si une méthode est précédée par le mot clé final,
elle ne peut être redéfinie.
•Si, dans une classe fille, un constructeur est défini sans
commencer par un appel de constructeur, Java insère un appel
du constructeur par défaut (sans paramètre) de la super classe
par l’instruction super().
•La classe dérivée n’hérite pas des constructeurs présents dans
les supers classes.
•Le constructeur de la classe dérivée doit s'occuper entièrement
de l'initialisation de l'objet
• Il peut toutefois faire appel au constructeur de la classe mère,
à l'aide de l'instruction super.
•Si la classe mère possède (explicitement) un constructeur
sans paramètres, la classe fille peut ne pas faire appel au
constructeur par le mot clé super.
•En revanche, si la classe mère possède seulement
des constructeurs avec paramètres,
la classe fille doit faire appel explicitement à l’un de ses
constructeurs au moyen du mot clé super.
•Si utilisée, super doit toujours être la première instruction du
constructeur de la classe dérivée.
Constructeur & Héritage
Quand une classe Mère admet un constructeur avec paramètre(s),
toutes ses classes filles doivent avoir au moins un constructeur. Et
chaque constructeur d’une classe fille doit appeler le constructeur
de la mère avec super comme première instruction.
public Class A{ public Class A{
public Class A{
int x; int x;
int x;
} public A(int x)
public A(int x)
{this.x=x;}
{this.x=x;}
public Class B extends }
}
A{
int y; public Class B extends
} public Class B extends
A{
A{
int y;
int y;
}
public B(int x,int y){
Super(x); this.y=y;
}}
Exemple
class Point{ class PointEspace extends
private double x,y ; Point{ private double z;
Point (double x, double y){ PointEspace(double x, double
this.x=x ; this.y=y;} y, double z ){super(x,y);
public double getX(){ return this.z=z;}
x); public double setZ(double z)
public double getY(){ return { this.z=z;);
y); public double getZ(){ return
public void deplacer( double z;};
xx, double yy){ } public void deplacer( double
x+=xx ; y+=yy ;} xx, double yy, double zz){
super.deplace();z+=zz ;} }
Visibilité (protected)
Protégé « protected », il est accessible de toute classe du
même package et de toutes ses classes dérivées même si elles
appartiennent à d’autres packages (à condition que la classe de
base soit public).
Modificateur private Défaut protected public
La classe elle-même OUI OUI OUI OUI
Sous classe et même NON OUI OUI OUI
package
Non sous classe et NON OUI OUI OUI
même package
Sous classe et package NON NON OUI OUI
≠
Non Sous classe et NON NON NON OUI
package≠
Méthode toString de la Classe Object
La méthode toString est définie dans la classe Object ;
en conséquence toutes les classes Java en hérite.
La méthode toString définie dans la classeObject ne fait
pas grand-chose :
elle renvoie le nom de la classe de l'objet concerné suivi
de l'adresse de cet objet.
Lorsqu'on définit une classe, il peut être très utile de
redéfinir la méthode toString afin de donner une
description satisfaisante des objets de cette classe.
Beaucoup de classes de l'API redéfinissent la
méthode toString.
Redéfinition des certaines méthodes de Object
Dans la classe Personne, on peut redéfinir toString de la
manière suivante:
public String toString{
return code+’’,’’+ nom+’’,’’+ prénom;
}
Avant la redéfinition de toString() Après la redéfinition de
toString()
Personne p=new Personne(‘’Akli’’,
’’Amel ’’); Personne p=new
Personne(‘’Akli’’, ‘’Amel’’);
System.out.println(p); affiche
Personne@1234 System.out.println(p); affiche 45
Akli Amel
Dans toute classe où on définit la
méthode toString(), la méthode
afficher devient comme suit ;
public void afficher() {
System.out.println( this);
}
La redéfinition de la méthode equals de Object
On la redéfinit pour la classe Point
public boolean equals( Object O){
if( O == nul) return false;
If ( ! (O instanceOf(Point)) return false;
Point P = (Point) O;
return x== P.x && y == P.y;
}
Opérateur instanceof
class B{ …}
class D extends B{…}
class C {…}
B b = new B();
D d = new D();
C c = new C();
b instanceof B // true
b instanceof D // false
d instanceof B // true
d instanceof D // true
b = d;
b instanceof B // true
b instanceof D // true
c instanceof B //erreur de compilation
Classes Abstraites
Une classe est dite abstraite si elle ne peut être instanciée
(ne peut produire d’instance). En java elle est définie par le
mot réservé abstract.
Soient les classes Masculin et Féminin. On peut factoriser
les attributs et méthodes communs des deux classes, on
obtient donc la super classe Personne.
Comme On ne peut avoir une personne qui ne soit ni
masculin ni féminin, la classe mère Personne ne doit pas
donner la possibilité de créer des objets et doit donc être
abstraite
Exemple de classe abstraite
public class Masculin extends Personne {
public abstract class Personne{ …….
private String nom, prenom, adresse, lieuNais ; public Masculin (String n, String p,
Date dateNais ; String ad,Date dN String lN)){
…….. super (n, p, ad, dN, lN) ;}
public Personne(String n, String p, String }
ad,Date dN String lN){
nom = n ; prenom= p ; adresse = ad, public class Feminin extends Personne {
dateNais= dN, lieuNais = lN ;} …….
public Feminin (String n, String p,
…………..} String ad,Date dN String lN)){
super (n, p, ad, dN, lN) ;}
}
}
Exemple de classe abstraite
Personne p1 = new Personne(….);
Type statique?
Personne p1 = new Feminin(….); oui
Type
dynamique?
Méthode abstraite
On peut aussi définir des méthodes abstraites. Elles sont
définies seulement par leurs signatures.
Une méthode abstraite est appelée à être redéfinie dans les
classes filles .
Vers les Méthodes abstraites
public abstract class Personne {
….
// pas de méthode sexe
}
public Feminin extends Personne public Masculin extends Personne
{…. {….
public char sexe(){ public char sexe(){
return ‘f’; return ‘m’;
}} }}
Dans le main, on considère:
Personne enfants =new Personne[2];
enfants[0]=new Feminin(......); enfants[1]=new Masculin(......);
for (int i=0; i<enfants.length;i++)
s.o.p(enfants[i].sexe()); Erreur de
compilation
Vers les Méthodes abstraites
public abstract class Personne {
Pas très
élégant
….
Public char sexe(){
return ‘?’;
}
}
public Feminin extends Personne public Masculin extends Personne
{…. {….
public char sexe(){ public char sexe(){
return ‘f’; return ‘m’;
}} }}
Dans le main, on considère:
Personne enfants =new Personne[2];
enfants[0]=new Feminin(......); enfants[1]=new Masculin(......);
for (int i=0; i<enfants.length;i++)
s.o.p(enfants[0].sexe());
correct
Méthode abstraite
public abstract class Personne {
Enfin la
bonne
….
soultion
public abstract char sexe();
public Feminin extends Personne public Masculin extends Personne
{…. {….
public char sexe(){ public char sexe(){
return ‘f’; return ‘m’;
}} }}
Dans le main, on considère:
Personne enfants =new Personne[2];
enfants[0]=new Feminin(......); enfants[1]=new Masculin(......);
for (int i=0; i<enfants.length;i++)
s.o.p(enfants[0].sexe());
correct