MODULE DE MISE À NIVEAU
EN JAVA
COURS 3
Laure KAHLEM
[email protected]
RÉFÉRENCES
Kathy Sierra et Bert Bates. Java Tête la
première. O’Reilly, 2007.
L. Kahlem- Programmation orientée objet
Mickaël Kerboeuf. Fondements de la
programmation orientée objet avec Java8.
Ellipses, 2016
David Flanagan. Java in a Nutshell. Manuel de
référence. O’Reilly, 2002.
Cyrille Herby. Apprenez à programmer en JAVA.
Broché, 2012.
José Paumard. « Java en ligne » [en ligne].
http://blog.paumard.org/cours/java/ (Consulté le
15/07/2015 ).
L’HÉRITAGE
Principes
L’héritage permet de mettre en œuvre la notion de
L. Kahlem- Programmation orientée objet
réutilisation.
L’héritage est une relation entre deux classes
qui permet à une classe de réutiliser les
caractéristiques d’une autre classe.
X Classe parent ou superclasse
Y Classe enfant ou sous-classe
L’HÉRITAGE
Exemple
Un compte bancaire peut soit être un compte
L. Kahlem- Programmation orientée objet
courant soit un compte d’épargne.
Un compte courant permet un solde négatif
mais des agios sont déduits chaque jour si le
solde est négatif.
Un compte d’épargne doit toujours avoir un
solde positif mais on ajoute des intérêts calculés
chaque jour.
L’HÉRITAGE
CompteBancaire
public void crediter (int montant)
L. Kahlem- Programmation orientée objet
public void debiter (int montant)
public String getNom ()
public void setNom(String nom)
public String getAdresse ()
public void setAdresse(String adresse)
public int getNumero()
public int getSolde()
CompteCourant CompteEpargne
- tauxAgios : double - tauxInterets : double
L’HÉRITAGE
Classe CompteCourant :
public class CompteCourant extends CompteBancaire{
L. Kahlem- Programmation orientée objet
private double tauxAgios; //taux quotidien des agios
à compléter
}
Classe CompteEpargne:
public class CompteEpargne extends CompteBancaire{
private double tauxInterets; //taux d’intérêts par jour
à compléter
}
L’HÉRITAGE
Constructeur de la sous-classe
La première instruction dans le constructeur de la
L. Kahlem- Programmation orientée objet
sous-classe doit être l’appel au constructeur de la
superclasse avec le mot clé super.
Si on ne fait pas d’appel explicite au constructeur
de la superclasse, c’est le constructeur par défaut
de la superclasse qui est appelé à condition qu’il
existe.
L’HÉRITAGE
Constructeur de la sous-classe
Exemple :
L. Kahlem- Programmation orientée objet
Classe CompteCourant :
//constructeur
public CompteCourant(String nom,String
adresse, double tauxAgios) {
super (nom, adresse);
this.tauxAgios = tauxAgios;
}
L’HÉRITAGE
Constructeur de la sous-classe
Exemple :
L. Kahlem- Programmation orientée objet
Classe CompteEpargne :
//constructeur
public CompteEpargne ( String nom,String
adresse, double tauxInterets) {
super ( nom, adresse );
this.tauxInterets = tauxInterets;
}
L’HÉRITAGE
La redéfinition de méthode
Certaines méthodes de la superclasse ne
L. Kahlem- Programmation orientée objet
conviennent pas pour la sous-classe.
On peut alors les redéfinir.
Dans ce cas, on utilisera le mot clé super pour
faire référence à la méthode de la superclasse.
L’HÉRITAGE
La redéfinition de méthode
Exemple : Redéfinir debiter pour la classe
L. Kahlem- Programmation orientée objet
CompteEpargne
//méthode debiter redéfinie
public void debiter ( double montant ) {
if ( montant <= getSolde ())
super.debiter ( montant );
else
System.out.println ( " Débit non
autorisé ");
}
L’HÉRITAGE
Polymorphisme
L. Kahlem- Programmation orientée objet
Possibilité de manipuler des objets sans
connaître leur type spécifique en utilisant
des méthodes polymorphes.
Possibilité d’affecter un objet d’une sous-
classe à une variable de la superclasse.
Exemple :
CompteBancaire c = new CompteEpargne(…);
L’HÉRITAGE
Quelles est la méthode appelée?
CompteBancaire c =
L. Kahlem- Programmation orientée objet
new CompteEpargne(‘Dupont’,’4 Rue d\’Illier’,
0.01); CompteBancaire
c.crediter(1000); +crediter(montant)
C.debiter(500); +debiter (montant)
C’est toujours la version la
plus spécifique de la CompteEpargne
méthode qui est appelée par
la JVM. +debiter (montant)
L’HÉRITAGE
Polymorphisme
Application : Une agence gère plusieurs comptes.
L. Kahlem- Programmation orientée objet
CompteBancaire[] agence = new
CompteBancaire[100];
nbComptes = 0;
CompteCourant c = new CompteCourant(…);
CompteEpargne e = new CompteEpargne(…);…
agence[0] = c; nbComptes++;
agence[1] = e; nbComptes++;…
for (int i =0;i<nbComptes; i++)
agence[i].debiter(100);
L’HÉRITAGE
Sur chaque compte, un traitement
quotidien est effectué:
L. Kahlem- Programmation orientée objet
Prélèvement des agios sur un compte
courant
Versement des intérêts sur un compte
d’épargne
L’HÉRITAGE
Sur chaque compte, un traitement
quotidien est effectué
L. Kahlem- Programmation orientée objet
Qu’ajoute-ton?
L’HÉRITAGE
Classes abstraites
Une classe abstraite est une classe qu’on ne
L. Kahlem- Programmation orientée objet
pourra pas instancier.
On la déclare avec le mot clé abstract.
Une classe abstraite pourra contenir certaines
méthodes non implémentées, on parle de
méthodes abstraites.
Si on déclare une méthode abstraite , la classe
doit également être abstraite.
L’HÉRITAGE
Classes abstraites
Exemple :
L. Kahlem- Programmation orientée objet
La classe CompteBancaire sera déclarée
abstraite car la méthode
traitementQuotidien est abstraite. Le
traitement à appliquer dépend du type de
compte et sera décrit dans les classes dérivées.
La classe CompteBancaire ne pourra pas être
instanciée.
L’HÉRITAGE
CompteBancaire
public void traitementQuotidien()
L. Kahlem- Programmation orientée objet
CompteEpargne
CompteCourant
traitementQuotidien()
traitementQuotidien()
L’HÉRITAGE
Classe CompteBancaire modifiée :
L. Kahlem- Programmation orientée objet
public abstract class CompteBancaire {
…
public abstract void traitementQuotidien();
}
L’HÉRITAGE
Définition de la méthode
traitementQuotidien dans chaque
L. Kahlem- Programmation orientée objet
sous-classe :
Classe CompteCourant :
public void traitementQuotidien () {
if (getSolde () < 0) {
debiter (-1.0*getSolde()*tauxAgios);
}
}
L’HÉRITAGE
Définition de la méthode
traitementQuotidien dans chaque
L. Kahlem- Programmation orientée objet
sous-classe :
Classe CompteEpargne:
public void traitementQuotidien () {
crediter (getSolde()* tauxInterets);
}
L’HÉRITAGE
Classes abstraites et polymorphisme
Application : Une agence gère plusieurs comptes.
L. Kahlem- Programmation orientée objet
CompteBancaire[] agence = new
CompteBancaire[100];nbComptes = 0;
CompteBancaire c = new CompteBancaire(…);
CompteCourant c = new CompteCourant(…);
CompteEpargne e = new CompteEpargne(…);…
agence[0] = c; nbComptes++;
agence[1] = e; nbComptes++;…
for (int i =0;i<nbComptes; i++)
agence[i].traitementQuotidien();
L’HÉRITAGE
La classe OBJECT
Toutes les classes sont dérivées de la classe
Object.
L. Kahlem- Programmation orientée objet
Chaque méthode de la classe Object est héritée
par toutes les classes.
Méthodes importantes de la classe Object :
public boolean equals ( Object o )
protected Object clone()
public final Class getClass()
public int hashcode()
public String toString()
L’HÉRITAGE
La classe OBJECT – La méthode equals
La méthode equals détermine si deux objets sont
L. Kahlem- Programmation orientée objet
égaux ou non.
Son implémentation dans la classe Object vérifie
que les références d’objets sont identiques.
On aura souvent besoin de redéfinir la méthode
equals : deux objets seront égaux quand ils
auront le même état.
L’HÉRITAGE
La classe OBJECT – La méthode equals
Redéfinir la méthode equals pour la classe
L. Kahlem- Programmation orientée objet
CompteBancaire
L’HÉRITAGE
public boolean equals(Object autre){
//tester si les objets sont identiques
if (this == autre) return true;
//doit renvoyer false si le paramètre explicite
vaut null
L. Kahlem- Programmation orientée objet
if (autre == null) return false;
//si les classes ne correspondent pas , elles ne
//peuvent être égales
if (getClass() != autre.getClass())
return false;
//autre est un objet de type CompteBancaire
//non null
CompteBancaire autreCompte
=(CompteBancaire)autre;
//tester si les comptes ont même numéro
return this.numero==
autreCompte.numero;
} //fin de la méthode equals
L’HÉRITAGE
La classe OBJECT – La méthode
hashCode
L. Kahlem- Programmation orientée objet
Un code de hachage est un entier dérivé d’un objet.
Par défaut, le code de hachage est extrait de
l’adresse mémoire de l’objet.
Des objets égaux ont toujours le même code de
hachage.
Deux objets ayant le même code de hachage ne
sont pas nécessairement égaux.
L’HÉRITAGE
La classe OBJECT – La méthode clone
La méthode clone renvoie une copie de l’objet.
L. Kahlem- Programmation orientée objet
Si la sous-classe ne redéfinit pas cette méthode,
elle effectue une copie champ par champ.
L’HÉRITAGE
La classe OBJECT – La méthode
toString
L. Kahlem- Programmation orientée objet
Il est conseillé de redéfinir la méthode toString.
L’appel de System.out.print ( o ) pour un
objet o va afficher le résultat de l’appel de
o.toString ().
L’HÉRITAGE
La classe OBJECT – La méthode
toString
L. Kahlem- Programmation orientée objet
Méthode toString()de la classe
CompteBancaire
public String toString (){
return " Compte numéro " + numero + "
ouvert au nom de " + nom + " \n Adresse
du titulaire " + adresse+ " \n Solde
actuel " + solde" ;
}
L’HÉRITAGE
La classe OBJECT – La méthode toString
L. Kahlem- Programmation orientée objet
Méthode toString()de la classe CompteCourant
public String toString(){
return " Compte courant " +super.toString();
}
Méthode toString() de la classe CompteEpargne
public String toString(){
return " Compte d’épargne "+super.toString();
}
LES INTERFACES
Définition d’une interface
Une interface peut être considérée comme une
classe 100% abstraite.
Une interface décrit une fonctionnalité sous
forme d’une liste de méthodes mais ne fournit
aucune implémentation de ces méthodes.
Une interface ne peut contenir de variable
d’instance.
Les seuls attributs autorisés sont les
constantes déclarées static et final.
Une interface ne peut être instanciée. 33
L.Kahlem- Programmation orientée objet
LES INTERFACES
Définition d’une interface
Toutes les méthodes d’une interface sont
implicitement publiques.
Une interface peut étendre plusieurs
interfaces.
A partir de Java 8, on peut ajouter deux
éléments supplémentaires dans une interface:
des méthodes statiques
des méthodes par défaut qui sont des
méthodes concrètes.
34
L.Kahlem- Programmation orientée objet
LES INTERFACES
Exemple d’interface définie dans
l’API Java : l’interface Comparable
L.Kahlem- Programmation orientée objet
C’est une interface générique paramétrée par
le type T.
Cette interface permet de définir une
relation d’ordre sur l’ensemble des objets
d’un type T.
35
LES INTERFACES
Exemple d’interface définie dans
l’API Java : l’interface Comparable
L.Kahlem- Programmation orientée objet
public interface Comparable <T> {
int compareTo( T o);
}
L’appel de x.compareTo(y) doit renvoyer
un entier négatif quand x<y,
un entier positif quand x>y,
0 quand x.equals(y)renvoie true (et
seulement dans ce cas).
36
LES INTERFACES
Implémentation des interfaces
Une interface définit un type.
public interface I0{
void m1 (…); Une interface peut
servir de type pour
void m2 ();
une variable, un
} attribut ou un
paramètre.
I0 varI0;
37
L.Kahlem- Programmation orientée objet
LES INTERFACES <<interface>>
I0
Implémentation des interfaces
Comment obtient-on un objet
possédant le type d’une interface?
A
1 - Définir une public class A implements I0{
classe qui void m1 (…){/* … */}
implémente void m2 (){/* … */}
l’interface }
2 - Instancier I0 varI0 = new A(); 38
cette classe
L.Kahlem- Programmation orientée objet
LES INTERFACES
Implémentation des interfaces
On utilise le mot clé implements pour nommer la
ou les interfaces qu’une classe implémente.
Une classe doit fournir une implémentation de
toutes les méthodes de chaque interface qu’elle
implémente excepté pour les méthodes par défaut.
Sinon elle doit être déclarée abstraite.
Une méthode par défaut peut être redéfinie dans la
classe qui implémente l’interface.
Une classe ne peut étendre qu’une seule classe mais
peut implémenter plusieurs interfaces.
39
L.Kahlem- Programmation orientée objet
LES INTERFACES
Polymorphisme
<<interface>> <<interface>> <<interface>> <<interface>>
Object I0 I2 I3a I3b
L.Kahlem- Programmation orientée objet
<<interface>>
<<interface>>
I1
A I3
Remonter les flèches d’héritage (pleines) et
les flèches d’implémentation (en pointillés)
permet de retrouver tous les types d’un 40
B objet .
LES INTERFACES
Utilité des interfaces
Les interfaces sont utilisées pour
représenter des propriétés transverses de
classes.
Exemple : Possibilité de définir une relation
d’ordre sur des objets quelque soit leur type
Interface Comparable<T>
De nombreuses classes de l’API Java offrent des
services pour des objets munis d’un ordre naturel.
41
L.Kahlem- Programmation orientée objet
LES INTERFACES
Utilité des interfaces
Exemple : Dans la classe java.util.Arrays :
public static void sort (Object[] a) trie
les éléments du tableau passé en paramètre à
condition que les éléments soient munis d’un ordre
naturel, i.e. implémentent l’interface Comparable.
42
L.Kahlem- Programmation orientée objet
LES INTERFACES
Utilité des interfaces
Supposons que l’on souhaite trier un ensemble
d’objets de type CompteBancaire suivant leur
numéro.
Pour utiliser la méthode public static sort
(Object[] a), il faut que la classe
CompteBancaire implémente l’interface
Comparable<CompteBancaire>.
43
L.Kahlem- Programmation orientée objet
LES INTERFACES
Utilité des interfaces
Exemple
public abstract class CompteBancaire
implements Comparable<CompteBancaire> {
…
public int compareTo (CompteBancaire o){
return this.numero – o.numero;
}
}
44
L.Kahlem- Programmation orientée objet
LES INTERFACES
Utilité des interfaces
Exemple
import java.util.*;
L.Kahlem- Programmation orientée objet
public class TestTableauCompteBancaire {
public static void main ( String[] args ){
CompteBancaire c1 =
new CompteCourant("Dupont", "a1",0.02);
c1.crediter(5000);
CompteBancaire c2 =
new CompteCourant("Martin", "a2",0.02);
c2.crediter(1000);
CompteBancaire c3 =
new CompteEpargne("Astruc", "a3",0.01,
22950);
c3.crediter(2000); 45
LES INTERFACES
Utilité des interfaces
Exemple
L.Kahlem- Programmation orientée objet
CompteBancaire[] tableauDeComptes =
{c3, c1, C2};
for (CompteBancaire compte : tableauDeComptes )
System.out.println( compte);
Arrays.sort ( tableauDeComptes );
for (CompteBancaire compte : tableauDeComptes )
System.out.println ( compte );
}//fin du main
}//fin de la classe TestTableauCompteBancaire
46
LES INTERFACES
Utilité des interfaces
Les interfaces sont utilisées pour définir
des types abstraits de données.
Permet de séparer l’usage extérieur de
l’objet de son implémentation.
Permet d’avoir plusieurs implémentations
interchangeables d’une même interface.
47
L.Kahlem- Programmation orientée objet
LES INTERFACES
Utilité des interfaces
Exemple : le type de données abstrait Pile.
On peut réaliser une pile avec un tableau ou une
liste chaînée.
Réalisation d’une pile avec une liste chaînée:
class Maillon {
Object valeur;
Maillon suivant;
public Maillon(Object s, Maillon m) {
valeur = s;
suivant = m;
} 48
}
L.Kahlem- Programmation orientée objet
LES INTERFACES
Utilité des interfaces
Exemple : le type de données abstrait Pile.
public class Pile { public Object depiler(){
private Maillon sommet; if (sommet ==null) return null;
Object valeur = sommet.getValeur();
public Pile() { sommet = sommet.getSuivant();
} return valeur;
public void empiler (Object s){ }
sommet = new Maillon(s, public Object sommet(){
sommet); if (sommet ==nul) return null;
} return sommet.getValeur();
public boolean estVide(){ }
return (sommet == null);
} } 49
L.Kahlem- Programmation orientée objet
LES INTERFACES
Utilité des interfaces
Exemple : le type de données abstrait Pile.
Pour séparer l’usage de la pile de son
implémentation, on extrait l’interface
publique de la classe :
public interface Pile {
void empiler (Object s);
boolean estVide();
Object depiler();
Object sommet();
50
}
L.Kahlem- Programmation orientée objet
LES INTERFACES
Utilité des interfaces
Exemple : le type de données abstrait Pile.
On rend privé les détails d’implémentation.
public class PileChainee implements Pile {
private Maillon sommet;
Partout où une
public Pile() { pile est requise,
} c’est par
public void empiler (Object s){
sommet = new Maillon(s, sommet); l’interface Pile
} qu’on la
public boolean estVide(){ désignera.
return (sommet == null);
} 51
L.Kahlem- Programmation orientée objet
LES INTERFACES
public Object depiler(){
if (sommet ==null) return null;
Object valeur = sommet.getValeur();
sommet = sommet.getSuivant();
return valeur;
}
public Object sommet(){
if (sommet ==nul) return null;
return sommet.getValeur();
}
private class Maillon {
Object valeur;
Maillon suivant;
public Maillon(Object s, Maillon m) {
valeur = s;
}
suivant = m; La classe Maillon
} est interne à la
}// fin de la classe PileChainee classe PileChainee
et privée 52
L.Kahlem- Programmation orientée objet
LES INTERFACES
On souhaite réaliser un jeu
permettant de se déplacer avec
L.Kahlem- Programmation orientée objet
différents moyens de locomotion,
voiture, moto, vélo, avion, train.
On sera amené à faire le plein dans
une station service lorsqu’on utilisera
une voiture ou une moto.
On pourra aussi changer une roue
d’un vélo, d’une moto et d’une
voiture. 53
LES INTERFACES
Choisir les classes permettant de
modéliser les différents moyens de
L.Kahlem- Programmation orientée objet
locomotion.
On souhaite maintenant ajouter la
possibilité de se déplacer avec un jet
ski.
54