Vous êtes sur la page 1sur 84

Programmation

Programmation Orientée
Orientée
Objet:
Objet: Java
Java

Sadok Ben Yahia, PhD


Faculté des Sciences de Tunis
sadok.benyahia@fst.rnu.tn

1
Plan

 Introduction au monde Objet


 La langage Java: Introduction et caractéristiques
 Syntaxe et structures de contrôle
 Héritage

 Les exceptions
 Les Entrées/Sorties
 Connexion Java et les bases de données: l’API JDBC

2
Héritage
 Extension d’une classe
 Intérêts

 Une application a besoin de services dont une partie seulement est

proposée par une classe déjà définie (on ne possède pas


nécessairement le code source de cette classe)
 Permet de ne pas réécrire tout le code

Une application a besoin de


manipuler des points (comme le
Classe Point permet la classe Point), mais en plus
• a une position de dessiner des points à l’écran

•peut être déplacé PointGraphique = Point


•peut calculer sa position + une couleur
+ une opération d’affichage
•…

 Une solution simple en POO : l’héritage (inheritance)


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

3
Héritage

 La classe PointGraphique hérite de la classe Point

PointGraphique
Hérite de Point
import java.awt.*; Elle possède les
variables
public class PointGraphique extends Point { Et méthodes définies
dans la classe Point
Color couleur ;

// affiche le point matérialisé par


// un rectangle de 3 pixels de côté PointGraphique
public void dessine(Graphics g) { Définit un nouvel
g.setColor (couleur) ; attribut
g.fillRect(x-1, y-1, 3, 3) ;
}
} PointGraphique
Définit une nouvelle
méthode

4
Héritage : Mécanismes
 Utilisation de la classe
PointGraphique  Comment cela se passe en mémoire
 Attributs et méthodes concernant les
 new créé un objet et retourne un
instances de la classe Point pointeur
s’appliquent aussi aux instances de
la classe PointGraphique
mémoire

p
PointGraphique p = new PointGraphique() ; isa

// utilisation des variables d’instance héritées 15


x
p.x = 15 ;
p.y = 11 ;
y 11
// utilisation d’une variable d’instance spécifique
p.couleur = new Color(255, 0, 0) ; Couleur
// utilisation d’une méthode héritée
double dist = p.distance() ;

// utilisation d’une méthode spécifique r 255


p.dessine(graphicContext) ;
v 0
0
b

5
Héritage : mécanismes

 Une classe est liée à sa super-classe par un lien kind-of (sorte-de)


Point
mémoire double x,y
void translater(…)
double distance()

Lien kind of
Partie statique
Structure de la classe PointGraphique
Color couleur
void dessine(…)
Partie dynamique
Structure des instances Lien isa

isa isa isa


x 22 x 15 x 56
y 14 y 11 y 14
couleur couleur couleur

 Une instance est liée à sa classe par un lien isa (est-un)


6
Héritage : mécanismes
 Propagation des messages
 Lorsqu’un message est envoyé à une instance, le lien isa

permet de trouver la classe de l’objet,


 puis la hiérarchie des classes est parcourue de manière

ascendante jusqu’à retrouver la méthode correspondante


Point Exécution du
mémoire double x,y Message
void translater(…) 3 (translation de p)
double distance()
Lien kind of
Partie statique
Structure de la classe PointGraphique
Color couleur
void dessine(…) 2
Partie dynamique
Structure des instances Lien isa p
Appel de méthode
isa isa isa (message)
1
x 22 x 15 x 56
y 14 y 11 y 14 p.translater(5,7)
couleur couleur couleur

7
Héritage : terminologie

 L’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 plus celles

définies dans F

 PointGraphique est la classe fille et Point la classe mère

 PointGraphique hérite de la classe Point

 La classe PointGraphique est une sous-classes de la classe Point

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

 La relation d’héritage (kind-of ou sorte-de) peut être vue comme une relation

de « généralisation/spécialisation » entre une classe et plusieurs classes

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


8
Héritage: Généralisation/spécialisation

 La généralisation exprime une relation est-un entre une classe et sa super-classe


 chaque instance de la classe est aussi « décrite » de façon plus générale par la

super-classe : elle est aussi une instance de la super-classe

Mammifère est une généralisation


d’Eléphant
Mammifère est un concept plus général
(abstrait) que Eléphant Mammifère
Eléphant est une-sorte de mammifère
généralisation

Eléphant
 L’héritage doit être utilisé
 Dans le sens «  généralisation » pour abstraire en factorisant les

propriétés communes à toutes les sous-classes


 Dans le sens « spécialisation » pour réutiliser par modification

incrémentielle les descriptions existantes

9
Héritage : Le test est-un

 Le test Est-un une règle simple pour savoir si 2 classes doivent être liées par
une relation d’héritage : si A peut être liée à B, la phrase “A est-un B” devrait
avoir du sens. Par exemple :
 un oiseau est un animal
 un chat est un mammifère
 une tarte aux pommes est une tarte
 une fenêtre de texte est une fenêtre
 une sphère est un objet graphique
 un tableau d’entiers est un tableau
 Par contre, les phrase suivantes sont inappropriées et donc l’héritage n’est pas
approprié :
 un oiseau est un mammifère
 une tarte au pomme est une pomme
 un moteur est une voiture
 un tableau d’entiers est un entier
10
Héritage…
 La relation d’héritage est transitive : les méthodes et les variables
sont héritées à travers tous les niveaux (sans limitation du nombre
de niveaux)

Équipement
Caractéristiques Caractéristiques
communes à tous les nom supplémentaires pour
équipements fabriquant les citernes
poids
coût

Pompe Échangeur Citerne


superficie volume
pression
diamètre pression
débit
longueur

Piston PompeCentrifuge CiterneSphérique


… …
taille nbrePales
axe diamètre

11
Héritage…

public class A {
C objc = new C() ;
public void hello() {
System.out.println(« hello ») ; objc.hello() ;
} objc.bye();
} objc.oups();
public class B extends A {

public void bye() {


System.out.println(« Bye bye »);
}
}

Public class C extends B { B objb = new B() ;


b.hello() ;
Public void oups() { b.bye();
System.out.println(« oups! ») ; b.oups();
}
}

12
Héritage…

 Héritage simple
 Une classe ne peut hériter que d’une seule autre classe

 Certains langages objets autorisent l’héritage multiple (ex. : C++)

 Problèmes liés à l’héritage multiple


 Conflit de noms de méthodes

 Le code peut devenir extrêmement difficile à interpréter

 La hiérarchie d’héritage est donc un arbre de racine Object


 Toute autre classe 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 Object

13
Héritage…

 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


 Lorsque la classe définit une méthode dont le nom, le type des
paramètres et le type de retour sont strictement identiques à ceux d’une
méthode dont elle hérite
 nom + types paramètres + type retour = signature

 Lorsqu’une méthode redéfinie par une classe est invoquée par un objet de
cette classe, c’est la nouvelle définition et non pas celle de la super-classe qui
est exécutée

14
Héritage…

public class A {

public void hello() {


System.out.println(« hello ») ;
}
A a = new A();
public void affiche() { B b = new B();
System.out.println(« je suis un A ») ;
}
a.hello() ; -->Hello
}
a.affiche(); -->Je suis un A

public class B extends A {


b.hello() ; -->Hello
b.affiche() ; -->Je suis un B
public void affiche() {
System.out.println(« Je suis un B ») ;
}

15
Héritage…

 Ne pas confondre redéfinition (overridding) avec surcharge (overloading)

public class A {
public void methodeX(int i) {
}
}

surcharge redéfinition

public class B extends A { public class C extends A {

public void methodeX(double i) { public void methodeX(int j) {


} }
} }

B possède deux méthodes C possède une seule méthode


• methodeX(int) • methodeX(int)
•methodeX(double)

 Il faut faire attention à la signature des méthodes !

16
Héritage…

 Redéfinition des méthodes (method overriding) :


 Possibilité de réutiliser le code de la méthode héritée (super) (redéfinition

avec réutilisation)

public class Etudiant {


String nom ;
String prenom ;
int age ;

public void affiche () {
System.out.println(“nom : ”+ nom + “prénom : ”+ prenom) ;
System.out.println(“Age : ”+ age);

}

} public class EtudiantSportif extends Etudiant {
String sportPratiqué ;

public void affiche() {
super.affiche() ;
System.out.println(“Sport pratiqué ” + sportPratiqué );
}

}

17
Héritage…

 Redéfinition et réutilisation des constructeurs


 Il est important de pouvoir réutiliser le code des constructeurs de la
super-classe dans la définition des constructeurs d’une nouvelle
classe
 En effet, souvent le constructeur a pour rôle d’initialiser les
variables d’instances
 invocation d’un constructeur de la super-classe :

super (paramètres du constructeur)

 utilisation de super analogue à celle de this (…)

18
Héritage…

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) ; L’appel au constructeur de la super-classe


this.c = c ; Doit toujours être la première instruction
} du corps du constructeur

}

19
Héritage : 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 1ère instruction n’est pas un appel de ce type, Java insère automatiquement l’appel
super()(constructeur par défaut sans paramètres)
 Chaque fois qu’un objet est créé, les constructeurs sont invoqués en remontant la hiérarchie
jusqu’à la classe Object
 C’est le corps du constructeur de la classe Object qui est toujours exécuté en 1er
 On peut dire que l’instance existe vraiment à partir du moment où le constructeur
d’Object a été exécuté. C’est pourquoi l’appel à super(…) doit être la 1ère instruction
 suivi du corps des constructeurs des différentes classes en redescendant la hiérarchie.
 Garantit qu’un constructeur d’une classe est toujours appelé lorsqu’une instance 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 instance C,
mais aussi de B et de A. Lorsqu’il est créé, il possède les caractéristiques de A, B et C

20
Héritage :chaînages des constructeurs

public class Object {

public object() { 3

} …
}

Ordre d’exécution
Ordre des appels
public class Point extends Object {
double x, y ;
public Point(double x, double y)
{ 2
super()
this.x = x ; this.y = y ;
}…
}

public class PointCouleur extends Point {


Color c ;

public PointCouleur(double x,double y,Color c){


super (x, y) ; 1
this.c = c ;
} … new PointCouleur(…);
}

21
Héritage : constructeur par défaut

 Lorsqu’une classe ne définit pas explicitement de constructeur, elle


possède quand même un constructeur par défaut
 Sans paramètres

 De corps vide

 Inexistant si un autre constructeur existe

public class Object {

public object() {

} …
}
Constructeur par défaut
public class A extends Object { implicite
String nom ; Garantit le chaînage des
constructeurs
A () {
String getNom() { super() ;
return nom ; }
}

}

22
Héritage : constructeur par défaut…

public class ClasseA {


double x;
// constructeur
public ClasseA(double x) { Constructeur explicite
this.x = x; Masque constructeur par défaut
}
}

public class ClasseB extends ClasseA {


double y = 0 ; public ClasseB {
Super();
// pas de constructeur }
} Constructeur par défaut implicite

C:> javac ClasseB.java


ClasseB.java:3: No constructor matching ClasseA() found in classe ClasseA.
public ClasseB() {
^
1 error

Compilation exited abnormally with code 1 at Sat Jan 29 09:34:24


23
Héritage : Redéfinition des attributs

 Lorsqu’une sous classe définit une variable d’instance dont le nom est
identique à l’une des variable dont elle hérite, la nouvelle définition masque
la définition héritée (shadowed variables)
 L’accès à la variable héritée se fait au travers de super

x instance de ClasseC

public class ClasseA { ((ClasseA) this).x


int x ;
}
super.super.x

public class ClasseB extends ClasseA {


double x ; super.x
}

this.x ou x
public class ClasseC extends ClasseB {
float x ;
}

 Il est fortement déconseillé de redéfinir les attributs !


24
Héritage
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
dont on peut avoir confiance (appelées méthodes get / set)
 Masque 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 à tout autre classe
 private n’est accessible qu’à l’intérieur de la classe où elle est définie
 protected est accessible dans la classe où il est défini et dans toutes ses
sous-classes (même d’autres packages)
 package (visibilité par défaut) accessible dans toutes les classes du même
package

25
Héritage
Visibilité des variables et méthodes

private - (package) protected public

La classe elle- oui oui oui oui


même

Classes du même non oui oui oui


package

Sous-classe d’un non non oui oui


autre package

Classes (non non non non oui


sous-classe) d’un
autre package

26
Héritage :visibilité des classes

 Deux niveaux de visibilité pour les classes


 public : la classe peut être utilisée par n’importe qu’elle autre classe

 - (package) : la classe ne peut être utilisée que par les classes

appartenant au même package


Package A Package B

package A ;
public class ClasseA {
ClasseB b ;
package B ;
}
public class ClasseC {

ClasseA a ;
package A ;
class ClasseB extends ClasseA { ClasseB b ;
… }

27
Héritage : méthodes finales
 Méthodes finales
 public final void methodX(…) {…}
 « verrouiller » la méthode pour interdire toute éventuelle redéfinition dans les sous-
classes
 Augmente l’efficacité du code
 quand le compilateur rencontre un appel à une méthode finale, il peut remplacer
l’appel habituel de méthode (empiler les arguments sur la pile, saut vers le code de la
méthode, retour au code appelant, dépilement des arguments, récupération de la
valeur de retour), par une copie du code du corps de la méthode (inline call).
si le corps de la méthode est trop gros, le compilateur est censé ne pas faire cette
optimisation qui serait contrebalancée par l’augmentation importante de la taille du
code.
Mieux vaut ne pas trop se reposer sur le compilateur :
– Utiliser final que lorsque le code n’est pas trop gros ou que l’on veut interdire toute
redéfinition
– Dans le cas des Classes membres (cf. cours GUI)
Méthodes private sont implicitement final (ne peuvent être redéfinies)

28
Héritage : Classes finales

 Une classe peut être définie comme finale

 public final Class UneClasse {…}

 Permet d’interdire tout héritage pour cette classe qui ne pourra être sous-

classée (utilisé notamment pour les classes qui gèrent la sécurité)

 Toutes les méthodes à l’intérieur de la classe seront implicitement finales

(elles ne pourront être redéfinies)

 Attention à l’usage de final, prendre garde à ne pas privilégier une supposée

efficacité au détriment des éventuelles possibilités de réutiliser la classe par

héritage.

29
Héritage : La classe Personne
abstract personne
#String nom
#String prénom
#String rue
#String ville
#static int nbpersonnes
+Personne( String nom, String prenom, String rue, String
ville)
+String toString()
+abstract void ecrirePersonne()
+static void nbPersonne()
+void modifierPersonne (String rue, String ville)

Enseignant Etudiant
Secretaire -String specialite -String diplomeEncours
-String numbureau
-static int nbEnseignants -static int nbEtudiants
-static int nbSeceratires +Enseignant( String nom, +Enseignant( String nom,
+Secretaire( String nom, String String prénom, String rue, String prénom, String rue,
prénom, String rue, String ville, String ville, String String ville, String
String numbureau) specialite) diplomeEncours)
+String toString() +String toString() +String toString()
+void ecrirePersonne() +void ecrirePersonne() +void ecrirePersonne()
+static int nbsecretaire() +static int nbenseignant() +static int nbetudiants()
30
La classe Personne: Implémentation
public String toString () {
abstract class Personne { // class
return nom + “ “ + prenom + “ “+ rue + “
abstraite, non instanciable “+ville; }
abstract void ecrirePersonne();
protected String nom;
static int nbpersonnes (){
protected String prenom; System.out.println(
“\n Nombre d’employés :“ + nbPersonnes
protected String rue;
+
protected String ville; “\n Nombre de secretaires : “ +
Secretaire.nbSecretaire() +
protected static int nbPersonnes=0; “\n Nombre d’enseignants : “ +
Personne (String nom, String prenom, Enseignant.nbEnseignant() +
“\n Nombre d’étudiants : “ +
String rue,String ville) Etudiant.nbEtudiant());
{this.nom=nom; }
void modifierPersonne (String rue,
this.prenom=prenom; String ville)
this.rue=ville; {this.rue=rue;
this.ville=ville;
this.ville=ville;
ecrirePersonne();}
nbpersonnes++;} }// fin Personne
31
La classe dérivée Secretaire: Implémentation

class Secretaire extends Personne {


private String numBureau;
private static int nbSecretaires;
Secretaire (String nom, String prenom, String rue,String ville,String numBureau)
{super(nom,prenom,rue,ville);
this.numBureau=numBureau;
nbSecretaires++;}

public String toString (){


return super.toString()+ “\n Numero de bureau : “ + numBureau;}
void ecrirePersonne()
{System.out.println(“Secretaire : “+toString())};

static int nbSecretaire ()


{ return nbSecretaires;}
}// fin Secretaire
32
La classe dérivée Enseignant:
Implémentation
class Enseignant extends Personne {
Private String specialite;
Private static int nbEnseignants;
Enseignant (String nom,String prenom, String rue,String ville,String specialite)
{super(nom,prenom,rue,ville);
this. specialite = specialite;
nbEnseignants++;}

String toString () {
return super.toString()+ “\n Specialité : “ + specialite;}
void ecrirePersonne()
{System.out.println(“Enseignant : “+toString())};

static int nbEnseignant ()


{ return nbEnseignants;}
}// fin Enseignant
33
La classe dérivée Etudiant: Implémentation
class Etudiant extends Personne {
private String diplomeEncours;
private static int nbEtudiants;
Etudiant (String nom, String prenom, String rue,String ville,String diplomeEncours)
{super(nom,prenom,rue,ville);
this. diplomeEncours = diplomeEncours;
nbEtudiants++;}

String toString () {
Return super.toString()+ “\n diplôme En cours : “ + diplomeEncours;}
void ecrirePersonne()
{System.out.println(“Etudiant : “+toString())};

static int nbEtudiant ()


{ return nbEtudiants;}
}// fin Etudiant
34
La classe main EssaiPersonne
class EssaiPersonne {
public static void main (String [] args)
{Secretaire sec1= new Secretaire (“Tounsi“, “Alia“, “Gambatta“, “tunis“,
“B128“);
Sec1.ecrirePersonne();
Enseignant ens1= new Enseignant (“Abidi“, “Hedi“, “Montfleury“, “tunis“,
“BD“);
ens1.ecrirePersonne();
Etudiant etud1= new Etudiant (“Samet“, “Ali“, “Manar“, “tunis“,
“Ingenieur“);
etud1.ecrirePersonne();
Personne.nbPersonnes();
Sec1.modifierPersonne(“Menzah“, “Tunis2“);
ens1.modifierPersonne(“Rades“, “Ben Arous“);
}}// fin EssaiPersonne
35
La classe main EssaiPersonne2
class EssaiPersonne2 {
public static void main (String [] args)
{Personne p;// seulement une référence
p= new Secretaire (“Tounsi“, “Alia“, “Gambatta“, “tunis“, “B128“);
p.ecrirePersonne()// ecrirePersonne() de secretaire;
p= new Enseignant (“Abidi“, “Hedi“, “Montfleury“, “tunis“, “BD“);
p.ecrirePersonne(); // ecrirePersonne() de Enseignant;
p = new Etudiant (“Samet“, “Ali“, “Manar“, “tunis“, “Ingenieur“);
p.ecrirePersonne(); // ecrirePersonne() de Enseignant;
Etudiant et1= (Etudiant) p;
Personne.nbPersonnes();
}}// fin EssaiPersonne2
36
Plan

 Introduction au monde Objet


 La langage Java: Introduction et caractéristiques
 Syntaxe et structures de contrôle
 Héritage

 Surclassement et Ploymorphysme
 Les exceptions
 Les Entrées/Sorties
 Connexion Java et les bases de données: l’API JDBC

37
Surclassement

 La réutilisation du code est un aspect important de l’héritage, mais ce

n’est peut être pas le plus important

 Le deuxième point fondamental est la relation qui relie une classe à sa

super-classe :

 Une classe B qui hérite de la classe A peut être vue comme un sous-

type (sous ensemble) plus spécialisé du type défini par la classe A.

 Tout objet instance de la classe B peut être aussi vu comme une

instance de la classe A.

38
Surclassement

 Surclassement (super-type = sous-type) :

À 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 (upcasting)

 Notez que le classe Object joue un rôle particulier car toute instance

de Object peut référer n’importe quel objet

39
Substitution de type

 Lasubstitution de type permet d’affecter une variable a de type plus général


qu’une variable b, en utilisant la substitution de type (“casting”).
 s = (String) obj ; avec obj de type Object

 Attention, cela n’est possible que si obj référence effectivement un objet de


type String. Sinon, une erreur est levée à l’exécution, de type :
ClassCastException
String s = new String(“une chaîne
quelqconque”) ;
Object obj ;

Obj = s ; surclassement

s = new String(“n’importe quoi”);

s = obj;

s = (String) obj ; substitution

40
Substitution de type: d’une manière générale

 Soient a et b deux objets, l’affectation a = b est possible


a et b appartiennent à la même classe

 la classe de b dérive de celle de a (sinon erreur à la compilation)

 L’affectation a= (<Type>) b est possible

 <Type> soit la même classe que a ou dérive de celle de a (sinon


erreur à la compilation)

b soit une instance de <Type> ou bien une instance d’une classe


dérivant de <Type> (sinon erreur à l’exécution)

41
Surclassement et substitution

 Lorsqu’un objet est « sur-classé » il est vu comme un objet du type de


la référence utilisée pour le désigner
 Ses fonctionnalités sont alors restreintes à celles proposées par la
classe du type de la référence
Etudiant
EtudiantSportif es ; String nom ;
es = new EtudiantSportif(“Tounsi”,“Ali”, String prénom ;
int age ;
20,..,”Bodybuilding”,..);

Etudiant e;
e = es ; // surclassement public Etudiant(String n,
es String p,int a …)
e public void affiche() {…}
e.affiche() ; public int nbInscriptions()
es.affiche() ;

e.nbInscriptions(); isa
es.nbInscriptions(); EtudiantSportif
Tounsi
String sportPratiqué;
es.bonusSportif(); …
Ali
e.bonusSportif(); 20 public EtudiantSportif(String n,
String p,int a …, String s, …)

Body... public void affiche() {…}


Il faut donc substituer e par :
public double bonusSportif()
((EtudiantSportif) e).bonusSportif();

42
Polymorphisme
 Polymorphisme : possibilité d’affecter à une référence d’un type donné
(i.e. une classe) une valeur qui désigne un objet du type de la référence ou d’une
sous classe de ce type
 A l’exécution, la référence peut désigner un objet qui prend des «  formes »

différentes selon sa classe effective Etudiant


 Quel est l’intérêt d’une telle utilisation des types ?
String nom ;
 Que va donner e.affiche() ? String prénom ;
Int age ;

Etudiant e = new EtudiantSportif(“Tounsi”,
“Ali”, 20, …, “Bodybuilding”, public Etudiant(String n,
String p,int a …)
…);
e public void affiche() {…}
public int nbInscriptions()
?
isa
e.affiche() ; EtudiantSportif
Tounsi
String sportPratiqué;
Ali …
?
20 public EtudiantSportif(String n,
String p,int a …, String s, …)

Body... public void affiche() {…}


public double bonusSportif()

43
Polymorphisme: Liens dynamiques

 Le polymorphisme qui est fondamental en programmation OO est rendu possible par le


fait que les messages sont résolus dynamiquement (message binding)

Lorsqu’une méthode d’un objet est


accédée au travers d’une référence Etudiant
“surclassée”, c’est la String nom ;
méthode définie au niveau de la String prénom ;
classe réelle de l’objet qui est Int age ;
invoquée et exécutée …
public Etudiant(String n,
Etudiant e = new EtudiantSportif(“Tounsi”, String p,int a …)
“Ali”, 20, …, “Bodybuilding”, public void affiche() {…}
e …); public int nbInscriptions()
?
isa e.affiche() ; EtudiantSportif
Tounsi String sportPratiqué;

Ali ?
public EtudiantSportif(String n,
20 String p,int a …, String s, …)

public void affiche() {…}


Body... public double bonusSportif()

44
Polymorphisme: Liens dynamiques

 Comment est-ce possible ?


 Les messages sont résolus à l’exécution (run-time)
À cet instant, le type exact de l’objet est connu
 Il y a un mécanisme pour retrouver le type d’un objet et appeler la
méthode appropriée au moment de l’exécution
 Ce mécanisme est désigné sous le terme de lien-dynamique
(dynamic binding, late-binding ou run-time binding)
 Le compilateur ne dispose pas de l’information nécessaire pour associer
le code d’une méthode à un message :
 Il ne connaît pas le type exact de l’objet récepteur d’un message
 Il n’effectue que les vérifications statiques qui permettent de garantir
que le message pourra être résolu au moment de l’exécution
45
Polymorphisme : Liens dynamiques

ClasseA a;
A
for (int i=0 ; i<10; i++) {
public void affiche() { hasard = Math.random();
System.out.println(“Je suis un A”); if (hasard < 0.33)
}
a=new ClasseA();
else if (hasard < 0.66)
a = new ClasseB();
else
B a = new ClasseC();

public void affiche() { a.affiche() ;


System.out.println(“Je suis un B”);
}

On peut afficher le type de a par :


C System.out.println(“Classe de a : ”+
a.getClass().getName());
public void affiche() {
System.out.println(“Je suis un C”); On peut aussi tester le type par :
} if(a instanceof C) -> true si a est
instance de C

46
Polymorphisme: Liens dynamiques

 A quoi servent l’upcasting et les liens dynamiques ?


 Upcasting et liaison des dynamique offrent toute sa dimension au

polymorphisme qui constitue «  la 3ème caractéristique essentielle


d’un langage orienté objet, après l’abstraction des données
(encapsulation et l’héritage) »

“Once you know that all method binding in Java


happens polymorphically via late binding, you can
always write your code to talk to the base class,
and know that all the derived-class cases will work
correctly using the same code. Or put it another
way, you send a message to an object and let the
object figure out the right thing to do”

Bruce Eckel «  Thinking in Java»

47
Polymorphisme : Intérêt

 Le polymorphisme associé à la liaison dynamique offre :

 Une plus grande simplicité du code


 Plus besoin de distinguer différents cas en fonction de la
classe de l’objet

 Et surtout une plus grande facilité d’évolution du code


 Les programmes sont plus facilement extensibles car il est
possible de définir de nouvelles fonctionnalités en héritant de
nouveaux types de données à partir d’une classe de base
commune sans avoir besoin de modifier le code qui manipule
l’interface de la classe de base
 En d’autres termes, vous pouvez écrire des programmes
capables de travailler avec du code (classes) qui n’existent pas
encore !

48
Polymorphisme
public class GroupeTd {
 liste peut contenir Etudiant[] liste = new Etudiant[] ;
des étudiants de n’importe quel type int nbEtudiants = 0;

Etudiant public void ajouter (Etudiant e){
if(nbEtudiants < liste.length)
String nom ; liste[nbEtudiants++] = e;
String prénom ;
Int age ;
}
… public void afficherListe {
public void affiche() { for(int I=0; I<nbEtudiants; i++)
System.out.println( liste[I].affiche();
“Nom : ”+nom+“\n” }
+“Prénom”+prénom +“\n” }
+“Age : ”+age+…) ;} Code inchangé

Nouvelle classe d’étudiants


EtudiantSportif EtudiantEtranger
String sportPratiqué;
String nationalité ;

public void affiche() { public void affiche() {


super.affiche(); super.affiche();
System.out.println(“Sport” : System.out.println(“Nationalité :”
+ sport+“\n” + …); +nationalité+“\n”+…);
} }

49
Plan
 Introduction au monde Objet
 La langage Java: Introduction et caractéristiques
 Syntaxe et structures de contrôle
 Héritage

 Surclassement et Ploymorphysme
 Les classes abstraites : Héritage et abstraction

 Les exceptions
 Les Entrées/Sorties
 Connexion Java et les bases de données: l’API JDBC

50
Classes Abstraites
Exemples introductifs
 Un grand classique : les formes géométriques
 On veut définir une application permettant de manipuler des formes
géométriques (triangles, rectangles, cercles,…).
 Chaque forme est définie par sa position sur l’écran

 Chaque forme peut être déplacée (modification de position), calculer son


périmètre, sa surface, etc.

largeur
v
r

hauteur
2
x,y
x,
x,y y v
1
Attributs : Attributs :
Attributs :
double x,y; //centre double x,y; // 1 sommet
double x,y; //coin inf-gauche
double r; // rayon double x1,y1; // v1
double largeur, hauteur;
Méthodes : double x2,y2; // v2
Méthodes :
déplacer(double dx,double dy) Méthodes :
déplacer(double dx,double dy)
double surface() déplacer(double dx,double dy)
double surface()
double périmètre() double surface()
double périmètre()
double périmètre()
Membres pouvant être factorisés

51
Classes Abstraites : Exemples introductifs…

largeur
v
r

hauteur
2
x,y
x,
x,y y v
1
class Forme { Forme
protected double x,y;
public void deplacer(double dx, double x,y;//centre du cercle
double dy) {
x += dx ; y += dy;
deplacer(double dx,double dy)
}
}
class Cercle extends Forme {
protected double r; Cercle Rectangle Triangle
public double surface(){ double largeur ; double x1,y1 ;
return Math.PI * r * r; double r;//rayon
double hauteur ; double x2,y2 ;
}
protected double périmetre() { double surface() double surface() double surface()
double périmetre() double périmetre() double périmetre()
return 2 * Math.PI * r;
}
}

52
Classes abstraites : Exemples introductif

import java.util.Vector;
class ListeDeFormes {
 On veut pouvoir gérer des
Vector liste ; ensembles de formes

public void ajouter(Forme f) { On exploite le polymorphisme.


liste.add(f); La prise en compte de
} nouveaux types ne modifie
pas le code
public void toutDeplacer(double dx,
double dy) {
for(int i=0; i<liste.size(); i++) Appel non valide car la
((Forme) méthode périmètre n’est pas
liste.elementAt(i)).deplacer(dx,dy); implémentée au niveau de la
} classe Forme
Définir une
public double périmetreTotal() { méthode périmètre
for (int i=0; i<liste.size(); i++) dans Forme ?
((Forme)
liste.elementAt(i)).périmetre(); public double périmetre() {
return 0.0; // ou -1 ??
}
 Une solution propre et élégante : les classes abstraites

53
Classes abstraites

 Utilité:
 Définir des concepts (classes) incomplets qui devront être implémentés dans

les sous-classes pour pouvoir être utilisés


 Permet de factoriser le code

 Ne peut pas être instanciée

abstract class Forme {


Classe abstraite
protected double x, y ;

public void deplacer(double dx, double


dy) {
x += dx ; y += dy ;
}

public abstract double périmetre() ;


Méthodes abstraites
public abstract double surface() ;

}
54
Classes abstraites

 Uneclasse abstraite est une classe non instanciable, c’est-à-dire


qu’elle n’admet pas d’instance directes. Impossible d’exécuter :
new AbsClass ()

 Uneopération abstraite est une 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
 Uneclasse pour laquelle au moins une méthode est abstraite doit être
déclarée 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 !!!)

55
Classes abstraites

 Une classe abstraite est une description d’objets. Elle est 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

 Touteclasse 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.

 Lafactorisation optimale des propriétés communes a plusieurs classes


par généralisation nécessite le plus souvent l’utilisation de classes
abstraites.

56
Classes abstraites

 Mieux structurer avec des classes et des opérations abstraites

Classe abstraite
FormeGéométrique
Méthode abstraite
Centre : Point

dessiner()

Classe abstraite car déplacer(delta:Vecteur) Classe concrète


(dessiner() est héritée et non
concrétisée

Elips …
Polygone
e
grandDiam :
Régulier : Boolean Vecteur
petitDiam : Vecteur
dessiner(
) Opération concrétisée
Polygone n’est utile que si spécialisée

57
Classes abstraites

Opérations abstraites et polymorphisme

Magnitude
Opérations abstraites
égalA(obj : Magnitude) : Boolean
{
inférieurA(obj : Magnitude) : Boolean
supérieurA(obj : Magnitude) :
Opérations concrètes
Boolean
(basées sur les deux
opérations abstraites)

Date Caractère … Nombre

Chaque sous-classe
concrète admet une Réel … Entier
implémentation différente
pour égalA() et inférieurA()

58
Plan
 Introduction au monde Objet
 La langage Java: Introduction et caractéristiques
 Syntaxe et structures de contrôle
 Héritage

 Surclassement et Ploymorphysme
 Les classes abstraites : Héritage et abstraction
 Les interfaces

 Les exceptions
 Les Entrées/Sorties
 Connexion Java et les bases de données: l’API JDBC
59
Interfaces : Intérêt

 Principe d'encapsulation: protéger au maximum les attributs d'un


objet
 => la modification des attributs passe obligatoirement par des
méthodes adaptées.
 Il peut être intéressant de protéger encore plus un objet afin qu'il
ne soit accessible que par un intermédiaire (un représentant).
 Java permet d'utiliser cette technique au moyen de l'interface.
Seules quelques méthodes sont autorisées à être utilisées. Ce sont
les méthodes désignées par l'interface. Comme son nom l'indique,
l'interface joue le rôle d'intermédiaire entre l'application et l'objet
sollicité.

60
Interfaces : Exemple d’Intérêt

 La classe FichePersonne: On désire qu'elle ne soit pas directement


accessible par les applications n°1 et n°2. La seule tolérance
admise pour ces deux applications est de permettre la visualisation
de la fiche de chacune des personnes. On utilise donc un
représentant de la classe qui est l'interface Visualisation et qui
valide la seule méthode affiche pour ce cas particulier.

61
Interfaces : Intérêt

 La technologie des objets distribués : qui permet de construire des


objets comme nous avons l'habitude de faire, mais qui ont la
particularité d'être accessibles depuis n'importe quel ordinateur du
réseau.

 Elle est intéressante: elle permet de construire les objets une fois
pour toute sur une machine  il n'est pas nécessaire de les
recopier sur tous les autres ordinateurs du réseau.
 Attention toutefois, ces objets restent sur l'ordinateur où ils ont été
créés. Ce sont des objets distants qui fonctionnent en permanence,
et donc la seule possibilité de les solliciter est de passer par des
requêtes sur le réseau, et donc de passer par des interfaces qui
utilisent les méthodes appropriées.
62
Interfaces : Intérêt

 L'application du client désire récupérer l'adresse d'une personne, elle


passe donc par le représentant de la classe FichePersonne qui est
l'interface RequêtePersonne qui dispose de la méthode getAdresse
(généralement, il existe plusieurs méthodes pour ce genre d'interface).
 On retrouve ici le même principe que pour les bases de données.

63
Interfaces : Hiérarchies différentes

 Il arrive assez souvent qu'on désire mettre en relation des objets

qui n'ont apparemment aucun rapport entre eux.

 C'est notamment le cas lorsqu'on désire afficher des objets qui

sont issus de hiérarchies différentes.

 Il suffit alors de prévoir une interface qui proposera une méthode

commune à l'ensemble des objets à afficher.

64
Interfaces : Hiérarchies différentes

 Les classes Cercle et Carré héritent de la classe Forme qui dispose de la


méthode Dessine. Par ailleurs, la classe Texte qui est totalement
indépendante de la première hiérarchie dispose également de la méthode
Dessine. Pour être sûr de dessiner un objet quelconque sur une fenêtre,
par exemple, il suffit de passer par l'interface Présentation qui dispose de
la méthode Dessine et qui spécifie donc que les objets associés à cette
interface vont obligatoirement implémenter cette méthode.

65
Interfaces : Intérêt

 Tout système d'exploitation qui supporte des interfaces graphiques

doit constamment surveiller l'environnement afin de détecter des

événements tels que la pression sur une touche du clavier ou sur

un bouton de la souris.

 Java contrôle complètement la manière dont les événements sont

transmis de la source d'événement (par exemple, un bouton ou un

élément de menu) à l'écouteur d'événement (event listener).

 N’importe quel objet peut être désigné comme écouteur

d'événement. Lorsqu'un événement arrive à la source, celle-ci

envoie une notification à tous les objets écouteurs d'événements.

66
Interfaces : Intérêt

 Comme il est possible d'avoir n'importe quel objet (issu d'une hiérarchie
quelconque) comme écouteur d'événement, il est nécessaire de passer par le
système d'interface. En fait, un objet écouteur est une instance d'une classe
qui implémente l'interface spéciale appelée interface écouteur (listener
interface). Dans l'exemple ci-dessus, deux écouteurs ont été mis en oeuvre,
l'objet relatif à un élément du menu et l'objet boutonCercle (dans ce cas de
figure, ils sont à la fois source et écouteur). Ils sont représentés par l'interface
ActionListener, et lorsqu'un un événement se produit (correspondant à un clic
sur un bouton de la souris ou la validation par le clavier) la méthode
actionPerformed est exécutée.

67
Interfaces : Définition
 Mais qu'est-ce qu'une interface ? Il s'agit essentiellement d'une
annonce (ou d'une promesse) indiquant qu'une classe
implémentera certaines méthodes. On utilise d'ailleurs le mot clé
implements pour signaler qu'une classe tiendra cette promesse.
 Définition d'une interface : Les interfaces contiennent uniquement
des définitions de constante et des déclarations de méthodes, sans
leur définition (autrement dit, que le prototype, et pas le corps). La
définition d'une interface se présente comme celle d'une classe.
 On utilise simplement le mot clé interface à la place de class

68
Interfaces : Définition

 Par essence, les méthodes d'une interface sont abstraites (puisqu'on n'en
fournit pas de définition) et publiques (puisqu'elles devront être redéfinies
plus tard). Néanmoins, il n'est pas nécessaire de mentionner les mots clés
public et abstract (on peut quand même le faire).
 Une interface peut être dotée des mêmes droits d'accès qu'une classe

(public ou droit de paquetage). Dans le cas où on désire avoir une interface


publique :

69
Interfaces : Implémentation d'une
interface
 Une classe peut "implémenter" une interface, ce qui se fait avec le mot
réservé implements ; on écrira par exemple :

 Alors, la classe A :
 dispose des constantes définies dans l'interface I.

 est contrainte à définir toutes les méthodes prototypées dans l'interface I ;

plus exactement, si la classe A ne définit pas toutes les méthodes


prototypées dans I, elle doit être déclarée abstraite et ne pourra donc pas
être instanciée.
70
Interfaces : Définition

 Sachant que la classe A implémente l'interface I, on sait (si A n'est pas


abstraite) qu'elle dispose de toutes les méthodes de cette interface I ; on a
un renseignement sur ce dont on peut disposer avec les instances de cette
classe (c'est à dire un renseignement sur "l'interface" au sens usuel du
terme). Concrètement, en reprenant l'exemple de la classe FichePersonne
avec l'interface Visualisation, on peut écrire :

71
Interfaces : Définition

 On peut donc définir des variables de type interface, ici de type


Visualisation ; on peut alors invoquer uniquement la méthode déclarée
dans Visualisation sur un objet référencé par une variable de type
Visualisation ou (si cela avait été le cas) utiliser les constantes définies
dans l'interface. Cela a des conséquences fondamentales sur les
possibilités de programmation.
 Les attributs et les méthodes d'une interface sont automatiquement
publics ; cela implique qu'une classe qui implémente une interface
devra déclarer publiques (avec le modificateur public) les méthodes de
l'interface qu'elle définit.
 Si une classe A implémente une interface I, une sous-classe B de A
implémente aussi automatiquement I ; une instance B pourra être
référencée par une variable de type I et bénéficiera, au moins par
héritage, des définitions des méthodes prototypées dans I.

72
Interfaces : Définition

 Une même classe peut implémenter plusieurs interfaces :

73
Variables de type interface et
polymorphisme

 Bien que la vocation d'une interface soit d'être implémentée par une
classe, on peut définir des variables de type interface :
 Bien entendu, on ne pourra pas affecter à i une référence à quelque chose

de type I puisqu'on ne peut pas instancier une interface (pas plus qu'on ne
pouvait instancier une classe abstraite !). En revanche, on pourra affecter à
i n'importe quelle référence à un objet d'une classe implémentant
l'interface I :

 De plus, à travers i, on pourra manipuler des objets de classes


quelconques, non nécessairement liées par héritage, pour peu que ces
classes implémentent l'interface I.

74
Exemple

 Une interface Affichable comporte une méthode affiche. Deux classes


Entier et Flottant implémentent cette interface (aucun lien d'héritage
n'apparaît ici). On crée un tableau hétérogène de références de type
Affichable qu'on remplit en instanciant des objets de type Entier et
Flottant.

75
Exemple

Je suis un entier de valeur 25


Je suis un flottant de valeur 1.25
Je suis un entier de valeur 42

76
Exemple2

 Une interface permet de mettre en connexion plusieurs hiérarchies de


classes, qui à priori n'ont aucuns lien communs entre elles, par
l'intermédiaire de méthodes spécifiques.

77
Exemple2

78
Interfaces et constantes

 L'essentiel du concept d'interface réside dans les en-têtes de méthodes qui


y figurent. Mais une interface peut aussi renfermer des constantes
symboliques qui seront alors accessibles à toutes les classes
implémentant l'interface :
 Ces constantes sont automatiquement considérées comme si elles avaient

été déclarées static et final. Il doit s'agir obligatoirement d'expressions


constantes. Elles sont accessibles en dehors d'une classe implémentant
l'interface. Par exemple, la constante MAXI de l'interface I se notera
simplement I.MAXI.

79
Dérivation d'une interface
 On peut définir une interface comme une généralisation d'une autre. On
utilise là encore le mot clé extends, ce qui conduit à parler d'héritage ou de
dérivation, et ce bien qu'il ne s'agisse en fait que d'emboîter simplement
des déclarations :
 En fait, la définition de I2 est totalement équivalente à :

80
Interfaces: Typage

 En fait, il est important de comprendre la différence entre la notion de


classe d’un objet et le type d’un objet
 La classe d’un objet définit comment l’objet est implémenté

 Le type d’un objet ne concerne que son interface, i.e. l’ensemble


des messages que l’on peut lui envoyer -> communication
 Type = “point de vue sur l’objet”

 Un objet peut avoir différents types et différentes classes peuvent


avoir le même type

 Les interfaces définissent de nouveaux types d’objets


 Héritage d’interface = sous-typage

 Bien sûr, la relation est étroite entre la notion de type et de classe.


Chaque classe (abstraite ou non) définit aussi un type d’objet.

81
Interfaces: Classe ou interface ?

 Les critères qui permettent de choisir entre la création d’une nouvelle classe ou
d’une interface. Pas de règles absolues, mais des principes :
 Définition d’une nouvelle sorte d’objet ? (plutôt classe)

 Définition d’une nouvelle structure de données ? (plutôt classe)

 Définition d’un nouveau type d’objet ? (classe ou interface)

 Définition d’un nouveau comportement ? (plutôt interface)

 Contraintes lié au code existant

 Question de la généricité et de la réutilisabilité

 Plus le code est générique, plus on a besoin des interfaces.

 Ex. : AWT et gestionnaires d’évènements

ActionListener

ItemListener

WindowListener

MouseListener

Etc.

82
Conclusion : Les formes d’héritage

 Utilisation conseillée de l’héritage :


 Pour spécialiser : La sous-classe est un cas particulier de la classe
parent.
 Pour spécifier : La classe définit un comportement qui est implanté
dans la sous-classe
 Pour augmenter : La sous-classe ajoute une fonctionnalité de la
classe parent, mais ne change pas le comportement hérité.
 Utilisation moins conseillée de l’héritage (mais pas proscrites) :

 Pour construire : Parfois, la sous-classe utilise le comportement de


la classe parent, mais n’est-pas-un sous-type de la classe parent.
 Pour limiter : La sous-classe limite l’utilisation du comportement
hérité de la classe parent.
 Pour varier : la classe parent et la sous-classe sont des variantes
l’une de l’autre. La relation classe/sous-classe est arbitraire.
 Pour combiner. La sous-classe hérite des éléments de plus d’une
classes. C’est l’héritage multiple.
83
Conclusion : Les bénéfices de l’héritage
 Bénéfices de l’héritage
 Réutilisation du code

 Partage du code

 Cohérence des interfaces/spécifications. Lorsque deux sous-classes héritent

d’une même classe, la cohérence est garantie


 Composants logiciels. Les classes sont vues comme des boites noires,

faciles à utiliser
 Prototypage rapide. Les programmes sont plus simples à écrire

 Les coûts de l’héritage

 Vitesse d’exécution. Les méthodes héritées qui doivent considérer un

nombre important de sous-classes sont souvent + lentes qu’un code


spécialisé.
 Taille des programmes. Une “bonne” structure de programme objet

multiplie la taille du code.


 Complexité.La programmation OO est une solution à la complexité des

programmes. Cependant, une sur-utilisation de l’héritage peut correspondre


à remplacer une forme de complexité par une autre. Comprendre le
déroulement d’un programme qui utilise intensivement l’héritage n’est pas
toujours très simple.
84

Vous aimerez peut-être aussi