Vous êtes sur la page 1sur 19

Les classes abstraites

Pr C THIAM
cthiam@univ-thies.sn

Pr C THIAM 1
Les classes abstraites
• Nous avons vu que l’héritage est un moyen de mutualiser du code dans
une classe parente.
• Parfois cette classe représente une abstraction pour laquelle il n’y a pas
vraiment de sens de créer une instance. Dans ce cas, on peut considérer
que la généralisation est abstraite.
• Note
• Par opposition, on appelle classe concrète une classe qui n’est pas abstraite.

Pr C THIAM 2
class Vehicule
public class Vehicule {
private final String marque;
protected float vitesse;
public Vehicule(String marque) {
this.marque = marque;
}
public void accelerer(float deltaVitesse) {
this.vitesse += deltaVitesse;
}
public void decelerer(float deltaVitesse) {
this.vitesse = Math.max(this.vitesse - deltaVitesse, 0f);
}
// ... }
Pr C THIAM 3
Déclarer une classe abstraite
• Cette classe Vehicule peut avoir plusieurs classes filles
comme Voiture ou Moto.
• Finalement, la classe Vehicule permet de faire apparaître un type à
travers lequel il sera possible de manipuler des instances de Voiture ou
de Moto.
• Il y a peu d’intérêt dans ce contexte à créer une instance de Vehicule.
• Nous pouvons très facilement l’empêcher en déclarant par exemple le
constructeur avec une portée protected.
• En Java, nous avons également la possibilité de déclarer cette classe
comme abstraite (abstract).

Pr C THIAM 4
class abstraite Vehicule
• public abstract class Vehicule {
• private final String marque;
• protected float vitesse;
• public Vehicule(String marque) {
• this.marque = marque;
• }
• public void accelerer(float deltaVitesse) {
• this.vitesse += deltaVitesse;
• }
• public void decelerer(float deltaVitesse) {
• this.vitesse = Math.max(this.vitesse - deltaVitesse, 0f);
• }
Pr C THIAM 5
• Le mot-clé abstract ajouté dans la déclaration de la classe indique
maintenant que cette classe représente une abstraction pour laquelle
il n’est pas possible de créer directement une instance de ce type

Pr C THIAM 6
• Vehicule v = new Vehicule("X"); // ERREUR DE COMPILATION : LA
CLASSE EST ABSTRAITE

• Note
• En Java, il n’est pas possible de combiner abstract et final dans la déclaration
d’une classe car cela n’aurait aucun sens. Une classe abstraite ne pouvant être
instanciée, il faut nécessairement qu’il existe une ou des classes filles.

Pr C THIAM 7
Déclarer une méthode abstraite

• Un classe abstraite peut déclarer des méthodes abstraites.


• Une méthode abstraite possède une signature mais pas de corps.
• Cela signifie qu’une classe qui hérite de cette méthode doit la
redéfinir pour en fournir une implémentation (sauf si cette classe est
elle-même abstraite).
• Par exemple, un véhicule peut donner son nombre de roues.
• Plutôt que d’utiliser un attribut pour stocker le nombre de roues, il
est possible de faire du nombre de roues une propriété abstraite de la
classe.

Pr C THIAM 8
• public abstract class Vehicule {
• private final String marque;
• protected float vitesse;
• public Vehicule(String marque) {
• this.marque = marque;
• }
• public abstract int getNbRoues();

• // ...

• }
Pr C THIAM 9
• Toutes les classes concrètes héritant de Vehicule doivent maintenant
fournir une implémentation de la méthode getNbRoues pour pouvoir
compiler.

Pr C THIAM 10
• public class Voiture extends Vehicule {

• public Voiture(String marque) {


• super(marque);
• }
• @Override
• public int getNbRoues() {
• return 4;
• }

• // ...
Pr C THIAM 11
• public class Moto extends Vehicule {

• public Moto(String marque) {


• super(marque);
• }
• @Override
• public int getNbRoues() {
• return 2;
• }

• // ...

• } Pr C THIAM 12
Une méthode abstraite
• Une méthode abstraite peut avoir plusieurs utilités.
• Comme dans l’exemple précédent, elle peut servir à gagner en
abstraction dans notre modèle.
• Mais elle peut aussi permettre à une classe fille d’adapter le
comportement d’un algorithme ou d’un composant logiciel.

Pr C THIAM 13
• public abstract class Tableur {
• public void mettreAJour() {
• tracerLignesEtColonnes();
• int premiereLigne = getPremiereLigneAffichee();
• int premiereColonne = getPremierColonneAffichee();
• int derniereLigne = getDerniereLigneAffichee();
• int derniereColonne = getDerniereColonneAffichee();

• for (int ligne = premiereLigne; ligne <= derniereLigne; ++ligne) {


• for (int colonne = premiereColonne; colonne <= derniereColonne; ++colonne) {
• String contenu = getContenu(ligne, colonne);
• afficherContenu(ligne, colonne, contenu);
• }
• }
• } Pr C THIAM 14
• protected abstract String getContenu(int ligne, int colonne);
• private void afficherContenu(int ligne, int colonne, String contenu) {
• // ...
• }
• private int getDerniereColonneAffichee() {
• // ...
• }
• private int getDerniereLigneAffichee() {
• // ...
• }

Pr C THIAM 15
• private int getPremierColonneAffichee() {
• // ...
• }
• private int getPremiereLigneAffichee() {
• // ...
• }
• private void tracerLignesEtColonnes() {
• // ...
• }
• }

Pr C THIAM 16
• Dans l’exemple ci-dessus, on imagine une classe Tableur qui permet
d’afficher un tableau à l’écran en fonction des lignes et des colonnes
visibles.
• Il s’agit d’une classe abstraite et les classes qui spécialisent cette
classe doivent fournir une implémentation de la méthode
abstraite getContenu afin de fournir le contenu de chaque cellule
affichée par le tableur.

Pr C THIAM 17
COLLECTION
• List<String> liste = new ArrayList<String>(); System.out.println(liste.contains("une première chaîne")); //
• liste.add("une première chaîne"); true
System.out.println(liste.contains("quelque chose qui n'est pas
• liste.add("une troisième chaîne");
dans la liste")); // false
• System.out.println(liste.size()); // 2
• // insertion d'un élément // suppression du dernier élément de la liste
liste.remove(liste.size() - 1);
• liste.add(1, "une seconde chaîne");
• System.out.println(liste.size()); // 3 // ajout de tous les éléments d'une autre liste à la fin de la liste
• for (String s : liste) { liste.addAll(Arrays.asList("une autre chaîne", "et encore une
autre chaîne"));
• System.out.println(s);
• } System.out.println(liste.size()); // 4

// [une première chaîne, une seconde chaîne, une autre chaîne,


• String premierElement = liste.get(0); et encore une autre chaîne]
System.out.println(liste);

Pr C THIAM 18
La classe LinkedList

• La classe java.util.LinkedList est une implémentation de


String premierElement = liste.get(0);
l’interface List. Sa représentation interne est une liste
doublement chaînée. Cela signifie que la classe LinkedList System.out.println(liste.contains("une première chaîne")); //
est très performante pour les opérations d’insertion et de true
suppression d’éléments. Par contre, l’accès aléatoire en System.out.println(liste.contains("quelque chose qui n'est pas
lecture aux éléments se fait en temps linéaire. Elle est donc
moins performante que la classe ArrayList sur ce point. dans la liste")); // false

• List<String> liste = new LinkedList<String>();


// suppression du dernier élément de la liste
• liste.add("une première chaîne"); liste.remove(liste.size() - 1);
• liste.add("une troisième chaîne");
• System.out.println(liste.size()); // 2 // ajout de tous les éléments d'une autre liste à la fin de la liste
liste.addAll(Arrays.asList("une autre chaîne", "et encore une
• // insertion d'un élément autre chaîne"));
• liste.add(1, "une seconde chaîne");
System.out.println(liste.size()); // 4
• System.out.println(liste.size()); // 3 System.out.println(liste);
• for (String s : liste) {
• System.out.println(s);
• }
Pr C THIAM 19

Vous aimerez peut-être aussi