Vous êtes sur la page 1sur 32

Chapitre 4

Héritage et polymorphisme
Introduction
Réutilisation :

— Comment utiliser une classe comme brique de base pour


concevoir d’autres classes ?

— Dans une conception objet on définit des associations


(relations) entre classes

— Dans cette introduction nous nous focaliserons sur une forme


d’association

— Un objet peut être créé à partir du « moule » d’un autre objet :

Héritage
Héritage
1) Extension d’une classe

2) Terminologie

3) Généralisation/Spécialisation

4) Héritage en Java

5) Redéfinition des méthodes

6) Réutilisation

7) Chaînage des constructeurs

8) Visibilité des variables et des méthodes


9) Classes et méthodes finales
1) Héritage : Exemple introductif
— Problématique:
- Une application a besoin de services dont une partie
seulement est proposée par une classe déjà défini.

- Ne pas réécrire le code


Application a besoin
Un Point •de manipuler des points
• a une position PointGraphique =
(comme le permet la classe
• peut être déplacé Point + une couleur
• peut calculer sa Point) + une opération
distance à l ’origine •mais en plus de les d’affichage
... affecter une couleur et les
dessiner sur l’écran.
— Solution en POO : l’héritage :

définir une nouvelle classe à partir de la classe déjà existante


Héritage : syntaxe java
— La classe PointGraphique hérite de la classe Point
PointGraphique.java
Import java.awt.Color;
Import java.awt.Graphics;
Public class PointGraphique extends Point {
Color coul;
//constructeur
Public PointGraphique(double x, double y, Color c)
this.x=x;
this.y=y;
this.coul=c;
}
//affiche le point matérialisé par un rectangle de 3
pixels de coté
public void dessine(Graphics g)
{
g.setColor(coul);
g.fillRect((int)x-1,(int)y-1,3,3);
}
}
Instances d’une classe
héritée
— Un objet instance de PointGraphique possède les attributs définit
dans PointGraphique ainsi que les attributs définit dans Point (un
PointGraphique est aussi un Point )

— Un objet instance de PointGraphique répond aux messages définis


par les méthodes décrites dans la classe PointGraphique et aussi à
ceux définis par les méthodes de la classe Point

PointGraphique p = new PointGraphique();


// utilisation des variables d’instance héritées
p.x = 15;
p.y = 11;
// utilisation d’une variable d’instance spécifique
p.coul = new Color(255,0,0);
// utilisation d’une méthode héritée
double dist = p.distance();
// utilisation d’une méthode spécifique
p.dessine(graphicContext);
2)Terminologie
— Héritage permet de reprendre les caractéristiques d’une classe M
existante pour les étendre et définir ainsi une nouvelle classe F qui
hérite de M.

— Les objets de F possèdent toutes les caractéristiques de M avec en en


plus celles définies dans F

- Point est la Classe Mère et PointGraphique la Classe Fille.

- la classe PointGraphique hérite de la classe Point

- la classe PointGraphique est une sous-classe de la classe Point

- la classe Point est la super-classe de la classe PointGraphique

— la relation d'héritage peut être vue comme une relation de

— “généralisation/spécialisation” entre une classe (la super-classe) et

— plusieurs classes plus spécialisées (ses sous-classes).


Héritage à travers tous les niveaux

public class A {
public void hello() { Pour résoudre un message, la hiérarchie
System.out.println(«Hello»); des classes est parcourue de manière
} ascendante jusqu’à trouver la méthode
} correspondante

public class B extends A {


public void bye() {
System.out.println(«Bye Bye»);
}
}
C c = new C();
c.hello();
c.bye();
public class C extends B {
public void oups() {
c.oups();
System.out.println(«oups!»);
}
}
5) Redéfinition des méthodes
— Une sous-classe peut ajouter des variables et/ou des
méthodes à celles qu'elle hérite de sa super-classe.

— Une sous-classe peut redéfinir (override) les méthodes


dont elle hérite et fournir ainsi des implémentations
spécialisées pour celles-ci.

— Redéfinition d’une méthode:


c’est lorsque la classe définit une méthode dont le nom, le
type de retour et les arguments sont identiques à ceux d’une
méthode dont elle hérite

— Lorsqu’une méthode redéfinie par une classe est invoquée


pour un objet de cette classe, c’est la nouvelle définition et
non pas celle de la super-classe qui est invoquée.
Redéfinition des méthodes

public class A {
public void hello() {
System.out.println(«Hello»);
}
public void affiche() {
System.out.println(«Je suis un A»); A a = new A();
} B b = new B();
} a.hello(); --> Hello
a.affiche(); -->Je suis un A
b.hello(); --> Hello
b.affiche(); -->Je suis un B
public class B extends A {
public void affiche() {
System.out.println(«Je suis un B»);}
}
Redéfinition des méthodes
— Ne pas confondre redéfinition (overriding) avec surcharge
(overloading)
public class A {
public void methodX(int i) {
...
}
}
Surcharge Redéfinition
public class B extends A { public class C extends A {
public void methodX(Color i) { public void methodX(int i) {
... ...
} }
} }

— B possède deux méthodes methodX(int) et methodX(Color)

— C possède une seule méthode methodX(int))


6) Réutilisation: redéfinition
— Redéfinition des méthodes possibilité de réutiliser le code de la méthode héritée
(super)
public class Etudiant {
String nom;
String prénom;
int age;
...
public void affiche() {
System.out.println("Nom : " + nom + " Prénom : " + prénom);
System.out.println("Age : " + age);
...
}
...
}

public class EtudiantSportif extends Etudiant {


String sportPratiqué;
...
public void affiche()
{
super.affiche();
System.out.println("Sport pratiqué : "+sportPratiqué);
...
}
}
Particularités de l’héritage en Java
— Héritage simple

- une classe ne peut hériter que d’une seule autre classe

- dans certains autres langages (ex C++) possibilité d’héritage multiple

— La hiérarchie d’héritage est un arbre dont la racine est la classe


Object (java.lang)

- toute classe autre que Object possède une super-classe

- toute classe hérite directement ou indirectement de la classe Object

- par défaut une classe qui ne définit pas de clause extends hérite de la

classe Object public class Point {


int x; // abscisse du point
int y; // ordonnée du point
...
}
Réutilisation des constructeurs
public class Point {
double x,y;
public Point(double x, double y)
{
this.x = x; this.y = y;
}
...
}

public class PointCouleur extends Point {


Color c;
public PointCouleur(double x, double y, Color c)
{
super(x,y);
this.c = c;
}
...
}

Appel du constructeur de la super-classe.


Cet appel si il est présent doit toujours être
la première instruction du corps du constructeur
7) Chaînage des constructeurs
— Appel à un constructeur de la super classe doit toujours être la première instruction
dans le corps du constructeur

- si la première instruction d'un constructeur n'est pas un appel explicite à l’un des
constructeur de la superclasse, alors JAVA insère implicitement l'appel super()

- chaque fois qu'un objet est créé les constructeurs sont invoqués en remontant en séquence
de classe en classe dans la hiérarchie jusqu'à la classe Object

- c'est le corps du constructeur de la classe Object qui est toujours exécuté en premier, suivi
du corps des constructeurs des différentes classes en redescendant dans la hiérarchie.

— Il est garantit qu'un constructeur d'une classe est toujours appelé lorsqu'une instance
de l'une de ses sous classes est créée.

- un objet c instance de C sous classe de B elle même sous classe de A est un objet de
classe C mais est aussi un objet de classe B et de classe A. Lorsqu’il est créé c doit l’être
avec les caractéristiques d ’un objet de A de B et de C
Constructeur par défaut
— Lorsqu'une classe ne définit pas explicitement de constructeur, elle possède un
constructeur par défaut :

- sans paramètres

- de corps vide

- inexistant si un autre constructeur existe

public class A extends Object{


public class Object { // attributs
public Object()
String nom;
{
...
// méthodes
} String getNom() {
... return nom;
} }
...
}

public A() {
Constructeur par défaut implicite
super();
}
8) Visibilité des variables et méthodes
— Principe d'encapsulation : les données propres à un objet ne sont accessibles qu'au
travers des méthodes de cet objet

- sécurité des données : elles ne sont accessibles qu'au travers de méthodes en lesquelles
on peut avoir confiance

- masquer l'implémentation : l'implémentation d'une classe peut être modifiée sans


remettre en cause le code utilisant celle-ci

— En JAVA possibilité de contrôler l'accessibilité (visibilité) des membres (variables et


méthodes) d'une classe

- public accessible à toute autre classe

- private n'est accessible qu'à l'intérieur de la classe où il est défini

- protected est accessible dans la classe où il est défini, dans toutes ses sous-classes et dans
toutes les classes du même package.

— package (visibilité par défaut) n'est accessible que dans les classes du même package
que celui de la classe où il est défini
Visibilité des variables et méthodes
Private protected public
La classe elle Oui Oui Oui
meme
Classes du Non Oui Oui
même
package
Sous-classes Non Oui oui
d'un
autre
package
Classes (non Non non oui
sous-classes)
d'un autre
package
Surclassement
— Tout objet instance de la classe B peut être aussi vu comme
une instance de la classe A.

— Cette relation est directement supportée par le langage


JAVA : à une référence déclarée de type A il est possible
d'affecter une valeur qui est une référence vers un objet de
type B.

— plus généralement à une référence d'un type donné, il est


possible d'affecter une valeur qui correspond à une référence
vers un objet dont le type effectif est n'importe quelle sous-
classe directe ou indirecte du type de la référence

Etudiant e;
e = new EtudiantSportif(...);
Polymorphisme
— Le terme polymorphisme décrit la caractéristique d'un élément qui
peut prendre plusieurs formes, comme l'eau qui se trouve à l'état
solide, liquide ou gazeux.

— En programmation Objet, on appelle polymorphisme

- le fait qu’un objet d’une classe puisse être manipulé comme s’il
appartenait à une autre classe.

- le fait que la même opération puisse se comporter différemment sur


différentes classes de la hiérarchie.

— "Le polymorphisme constitue la troisième caractéristique essentielle


d'un langage orienté objet après l'abstraction des données
(encapsulation) et l'héritage »Bruce Eckel "Thinking in JAVA"
suite
— En utilisant le polymorphisme en association à la liaison
dynamique plus besoin de distinguer différents cas.

— Développement plus rapide


— Plus grande simplicité et meilleure organisation du code
— Programmes plus facilement extensibles
— Maintenance du code plus aisée
Classes abstraites
— Utilité :
- définir des concepts incomplets qui devront être
implémentés dans les sous classes

- factoriser le code

public abstract class forme{


protected double x,y;
public void deplacer(double dx,
double dy) {
x += dx; y += dy;
}

Public abstract double perimetre();


Public abstract double surface();
};
Classes abstraites
— Classe abstraite : classe non instanciable, c'est à dire qu'elle n'admet pas
d'instances directes.

- Impossible de faire new ClasseAbstraite(…);

— Opération abstraite : opération n'admettant pas d'implémentation

- au niveau de la classe dans laquelle elle est déclarée, on ne peut pas dire comment
la réaliser.

— Une classe pour laquelle au moins une opération abstraite est déclarée est une
classe abstraite (l'inverse n'est pas vrai).

— Les opérations abstraites sont particulièrement utiles pour mettre en oeuvre le


polymorphisme.

- l'utilisation du nom d'une classe abstraite comme type pour une (des) référence(s)
est toujours possible (et souvent souhaitable !!!)
Classes abstraites
— Une classe abstraite est une description d'objets destinée à être héritée par des
classes plus spécialisées.

— Pour être utile, une classe abstraite doit admettre des classes descendantes
concrètes.

— Toute classe concrète sous-classe d'une classe abstraite doit “concrétiser”


toutes les opérations abstraites de cette dernière.

— Une classe abstraite permet de regrouper certaines caractéristiques communes


à ses sous-classes et définit un comportement minimal commun.

— La factorisation optimale des propriétés communes à plusieurs classes par


généralisation nécessite le plus souvent l'utilisation de classes abstraites.
Les interfaces
— Toutes les méthodes sont abstraites

— Possibilité d’héritage de plusieurs interfaces

— Les interfaces permettent de s ’affranchir d ’éventuelles


contraintes d’héritage.

- Lorsqu’on examine une classe implémentant une ou plusieurs


interfaces, on est sûr que le code d’implémentation est dans le
corps de la classe. Excellente localisation du code (défaut de
l’héritage multiple).

— Permet une grande évolutivité du modèle objet


uelques notions: Les objets temporaires
— Dans une expression, on peut faire appel explicitement au
constructeur d'un objet : celui-ci est construit, mais nous n'y
avons pas accès (pour le modifier par exemple).

— Cet objet temporaire est construit pour les besoins d'évaluation


de l'expression puis abandonné.

— L'espace mémoire qu'il occupait sera automatiquement


récupéré ultérieurement par un programme appelé
"ramasse- miettes" dont le rôle est de récupérer l'espace
mémoire occupé par des objets qui ne sont plus référencés
par des données du programme.
Exemple 1
— Import Point;
public class test1{
public static void main(String arg[]){
( new Point ( 0.5,-3) ). affiche();
}
}

— La classe Point:

class Point {
double x;
double y;
void Point(double x,double y){
this.x = x;
this.y = y;
}
void affiche(){
System.out.println(« les coordonnées sont »+x « et »+y);
}}
Exemple 2
— Import PointGraphique;
public class test1{
public static void main(String arg[]){
new PointGraphique( (new PointGraphique ( 2, 5,Color.reed)). affiche();
}}

et modifions les constructeurs de la classe PointGraphique afin qu'ils


affichent un message :
// constructeurs
public PointGraphique (float x, float y, Color c){
initialise(x,y,c);
System.out.println("Constructeur PointGraphique (float, float,
Coleur) »)}

public PointGraphique (PointGraphique P){


initialise(P);
System.out.println("Constructeur PointGraphique (PointGraphique)");

}
Exécution

— Constructeur PointGraphique (float, float, Coleur))

— Constructeur PointGraphique (PointGraphique)

— 2,5, reed
Tableau d’objet
— Un objet est une donnée comme une autre et à ce titre plusieurs
objets peuvent être rassemblés dans un tableau :

Import PointGraphique;

public class test1{


public static void main(String arg[]){

PointGraphique [ ] Pts=new PointGraphique [3];

Pts [0] =new PointGraphique ( -1, 0.5,Color.blue);


Pts [1] =new PointGraphique ( 2, 3,Color.black);
Pts [2] =new PointGraphique ( 1.5, 0.5,Color.green);

for(int i=0;i<Pts.length;i++) Pts[i].affiche();

}}
Les paquetages
Pour écrire une ligne à l'écran, nous utilisons l'instruction
System.out.println(...)

Si nous regardons la définition de la classe System nous


découvrons qu'elle s'appelle en fait java.lang.System :

On peut le Vérifier le sur l’ exemple :

public class test1{


public static void main(String[] args){
java.lang.System.out.println("Coucou"); }}

Comme pour tout programme Java, il y a une importation


systématique du "paquetage" java.lang (import java.lang.*; )

Pour créer une classe dans un paquetage, on écrit :

package paquetage;

// définition de la classe ...


Tableau d’objet
— Cette classe est compilée puis placée dans un répertoire
paquetage du répertoire courant

Afin d’ utiliser la classe Point dans une première classe de test :


public class test{

public static void main(String[] args){


paquetage.Point p1=new paquetage.Point ( 1,2, Color.green);

}}

Pour eviter cettte déclaration on utilise soit

Import paquetage;

Ou

Import paquetage.Point;

Vous aimerez peut-être aussi