Vous êtes sur la page 1sur 30

Informatique / Programmation

Programmation oriente objet avec Java


13 : Classes abstraites et interfaces

Jacques Bapst
jacques.bapst@hefr.ch

Java / Classes abstraites et interfaces

Classes et mthodes abstraites


Une classe abstraite est une classe qui contient une ou plusieurs
mthodes abstraites. Elle peut malgr tout contenir d'autres
mthodes habituelles (appele parfois mthodes concrtes).
Une mthode abstraite est une mthode qui ne contient pas
de corps. Elle possde simplement une signature de dfinition
suivie du caractre point-virgule (pas de bloc d'instructions).
Une mthode abstraite doit obligatoirement tre dclare avec
le modificateur abstract.

Exemple :

public abstract double area();

Une classe possdant une ou plusieurs mthodes abstraites


devient obligatoirement une classe abstraite. Cette classe doit
galement tre dclare avec le modificateur abstract.

EIA-FR / Jacques Bapst

PR1_13

Java / Classes abstraites et interfaces

Classes abstraites : mtaphore


Comme les autres classes (et les interfaces), une classe abstraite
dfinit un nouveau type qui peut tre associ un identificateur
(dclaration de variables, champs, tableaux, paramtres formels, ).
Comme nous l'avons vu dans un des chapitres prcdents, les
classes peuvent tre considres comme tant des moules (des
modles, des plans, ...) permettant de fabriquer des objets.
Si l'on poursuit avec cette mtaphore, les classes abstraites
peuvent tre considres comme tant des moules incomplets
(des modles partiels, des plans non termins, ...) qui ne
peuvent pas tre utiliss tels quels pour crer des objets mais qui
peuvent tre utiliss pour fabriquer d'autres plans plus prcis
(reprsents par des sous-classes) qui seront complts et qui
permettront, eux, de crer des objets (des instances des sousclasses).

EIA-FR / Jacques Bapst

PR1_13

Java / Classes abstraites et interfaces

Classes abstraites

Classe
abstraite

extends

Classe
concrte

new

Instances
(Objets)

Objet 1

Objet 2

Objet 3

EIA-FR / Jacques Bapst

PR1_13

Java / Classes abstraites et interfaces

Classes abstraites : rgles [1]


Les rgles suivantes s'appliquent aux classes abstraites :
Une classe abstraite ne peut pas tre instancie : on ne peut pas
crer d'objet en utilisant l'oprateur new.
Une sous-classe d'une classe abstraite ne peut tre instancie que
si elle redfinit chaque mthode abstraite de sa classe parente et
qu'elle fournit une implmentation (un corps) pour chacune des
mthodes abstraites.
Une telle sous-classe est souvent appele sous-classe concrte afin
de mettre en vidence le fait qu'elle n'est pas abstraite.

Si une sous-classe d'une classe abstraite n'implmente pas toutes les


mthodes abstraites dont elle hrite, cette sous-classe est elle-mme
abstraite (et ne peut donc pas tre instancie).
Les mthodes dclares avec l'un des modificateurs suivants :
static, private ou final ne peuvent pas tre abstraites tant donn
qu'elles ne peuvent pas tre redfinies dans une sous-classe.

EIA-FR / Jacques Bapst

PR1_13

Java / Classes abstraites et interfaces

Classes abstraites : rgles [2]


Autres rgles s'appliquant aux classes abstraites :
Une classe dclare final ne peut pas contenir de mthodes
abstraites car elle ne peut pas tre sous-classe.
Une classe peut tre dclare abstract mme si elle ne possde
pas rellement de mthode abstraite.
Cela signifie que son implmentation est incomplte en certains
points (p. ex. le corps de certaines mthodes doit tre complt
en fonction du contexte) et qu'elle est destine jouer le rle de
classe parente pour une ou plusieurs sous-classes qui achveront
l'implmentation.
Mme si elle ne possde pas de mthodes abstraites, une telle
classe ne peut pas tre instancie (erreur la compilation).

EIA-FR / Jacques Bapst

PR1_13

Java / Classes abstraites et interfaces

Utilit des classes abstraites


En pratique, les classes abstraites permettent de dfinir des
fonctionnalits (des comportements) que les sous-classes
devront imprativement implmenter mme si la classe
abstraite n'est pas en mesure de fournir elle-mme une
implmentation pour ces mthodes.

Les utilisateurs des sous-classes d'une classe abstraite sont donc


assurs de trouver toutes les mthodes dfinies dans la classe
abstraite dans chacune des sous-classes concrtes.
Les classes abstraites constituent donc une sorte de contrat
(spcification contraignante) qui garantit que certaines mthodes
seront disponibles dans les sous-classes et qui oblige les
programmeurs les implmenter dans toutes les sous-classes
concrtes.

EIA-FR / Jacques Bapst

PR1_13

Java / Classes abstraites et interfaces

Exemple de classe abstraite [1]


Si l'on souhaite, par exemple, crer une hirarchie de classes qui
dcrive des formes gomtriques deux dimensions, on pourrait
envisager l'arborescence reprsente par le diagramme de classes
suivant :
Shape

Circle

Rectangle

Square

EIA-FR / Jacques Bapst

Triangle

...

...

PR1_13

Java / Classes abstraites et interfaces

Exemple de classe abstraite [2]


Sachant que toutes les formes possdent les proprits
primtre et surface, il est judicieux de placer les mthodes
dfinissant ces proprits (perimeter() et area()) dans la
classe qui est la racine de l'arborescence (Shape).
La classe Shape ne peut cependant pas implmenter ces deux
mthodes car on ne peut pas calculer le primtre et la surface
sans connatre le dtail de la forme.
On pourrait naturellement implmenter ces mthodes dans
chacune des sous-classes de Shape mais il n'y a aucune garantie
que toutes les sous-classes les possdent (ce serait laiss au
bon vouloir des programmeurs des sous-classes).
Il est possible de rsoudre ce problme en dclarant dans la
classe Shape deux mthodes abstraites perimeter() et area()
ce qui rend la classe Shape elle-mme abstraite et impose aux
crateurs de sous-classes de les implmenter.
EIA-FR / Jacques Bapst

PR1_13

Java / Classes abstraites et interfaces

Exemple de classe abstraite [3]


//----------------------------------------------------------// Shape
//----------------------------------------------------------public abstract class Shape {
// Classe abstraite
public abstract double perimeter(); // Mthode abstraite
public abstract double area();
// Mthode abstraite
}

//----------------------------------------------------------// Circle
//----------------------------------------------------------public class Circle extends Shape {
public static final double PI = 3.14159265358979;
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getRadius() { return radius; }
public double perimeter() { return 2*PI*radius; }
public double area()

{ return PI*radius*radius; }

}
EIA-FR / Jacques Bapst

PR1_13

10

Java / Classes abstraites et interfaces

Exemple de classe abstraite [4]


//----------------------------------------------------------// Rectangle
//----------------------------------------------------------public class Rectangle extends Shape {
protected double length, width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
public double getLength()

{ return length; }

public double getWidth()

{ return width; }

public double perimetre() {


return 2*(length + width);
}
public double surface() {
return length * width;
}
}
EIA-FR / Jacques Bapst

PR1_13

11

Java / Classes abstraites et interfaces

Exemple de classe abstraite [5]


Les autres sous-classes (Square, Triangle, ...) pourraient tre
implmentes selon le mme modle.
Mme si la classe Shape est abstraite, il est tout de mme possible
de dclarer des variables de ce type qui pourront recevoir des
objets crs partir des sous-classes concrtes :
Shape[] drawing = new Shape[3];
drawing[0] = new Rectangle(2.5, 6.8);
drawing[1] = new Circle(4.66);
drawing[2] = new Square(0.125);

// Conversion largissante
// Conversion largissante
// Conversion largissante

Le polymorphisme permet ensuite d'invoquer une mthode


commune sur chacun des objets :
double totalArea = 0.0;
for (int i=0; i<drawing.length; i++) {
totalArea += drawing[i].area();
}

EIA-FR / Jacques Bapst

// Calcule la somme
// des surfaces

PR1_13

12

Java / Classes abstraites et interfaces

Interface [1]
Comme une classe et une classe abstraite, une interface permet
de dfinir un nouveau type (rfrence).
Le comportement des objets de ce type (les oprations que l'on
peut effectuer) sera dtermin par le contenu (la dfinition) de
cette interface.

Une interface constitue essentiellement une spcification qui


laisse de ct les dtails d'implmentation.
L'interface dfinit ainsi une sorte de contrat que les classes qui
l'implmenteront s'engagent respecter.

Les interfaces jouent un rle important dans la phase de


conception (API) d'applications, de librairies ou de systmes
bass sur des ensembles d'objets qui communiquent.
Par certains aspects, la notion d'interface est assez proche de
la notion de classe abstraite mais elle comporte cependant un
certain nombre de spcificits qui l'en distinguent et qui en
tendent le potentiel.
EIA-FR / Jacques Bapst

PR1_13

13

Java / Classes abstraites et interfaces

Interface [2]
Du point de vue syntaxique, la dfinition d'une interface est proche
de celle d'une classe abstraite.
Il suffit de remplacer les mots-cls abstract class par le motcl interface :
public interface Printable {
public void print();
}
Une fois l'interface dclare, il est possible de dclarer des
variables de ce (nouveau) type :
Printable
Printable[]

EIA-FR / Jacques Bapst

document;
printSpool;

PR1_13

14

Java / Classes abstraites et interfaces

Interface [3]
Le corps d'une interface peut contenir :
Des constantes qui sont implicitement publiques
Les modificateurs static et final ne sont pas ncessaires (implicites).

Des mthodes abstraites qui sont obligatoirement publiques


Le modificateur abstract n'est pas ncessaire (implicite).
Le modificateur public n'est pas ncessaire (implicite).

Des mthodes avec une implmentation par dfaut


Le modificateur default doit tre utilis.

Des mthodes statiques

Par contre
Une interface ne peut pas dfinir de champs d'instance.

Une interface ne dfinit pas de constructeur (on ne peut pas


l'instancier et elle n'intervient pas dans le chanage des constructeurs).

EIA-FR / Jacques Bapst

PR1_13

15

Java / Classes abstraites et interfaces

Utilisation des interfaces [1]


En Java, une classe ne peut hriter que d'une et d'une seule classe
parente (hritage simple).
Une classe peut, par contre, implmenter une ou plusieurs
interfaces en utilisant la syntaxe suivante :

implements interface1, interface2, ...


L'implmentation d'une ou de plusieurs interfaces (implements) peut
tre combine avec l'hritage simple (extends).
La clause implements doit suivre la clause extends.

Exemples :
public class Report

implements Printable {...}

public class Book

implements Printable, Zoomable {...}

public class Circle

extends Shape implements Printable {...}

public class Square

extends Rectangle
implements Printable, Zoomable {...}

EIA-FR / Jacques Bapst

PR1_13

16

Java / Classes abstraites et interfaces

Utilisation des interfaces [2]


Lorsqu'une classe dclare une interface dans sa clause
implements, elle indique ainsi qu'elle s'engage fournir une
implmentation (c'est--dire un corps) pour chacune des
mthodes abstraites de cette interface.
Si une classe implmente une interface mais ne fournit pas
d'implmentation pour toutes les mthodes abstraites de l'interface,
elle hrite des mthodes (abstraites) non implmentes de
l'interface et doit elle-mme tre dclare abstract.
Si une classe implmente plus d'une interface, elle doit implmenter
toutes les mthodes abstraites de chacune des interfaces
mentionnes dans la clause implements (ou alors tre dclare
abstract).

Les mthodes de l'interface qui sont dclares avec une


implmentation par dfaut peuvent tre redfinies (ou non) dans
les classes qui implmentent l'interface.
EIA-FR / Jacques Bapst

PR1_13

17

Java / Classes abstraites et interfaces

Exemple d'interface [1]


Si l'on souhaite caractriser la fonctionnalit de comparaison qui
est commune tous les objets qui ont une relation d'ordre (plus
petit, gal, plus grand), on peut dfinir l'interface Comparable de la
manire suivante :
public interface Comparable {

public int compareTo(Object v);

Cette interface dfinit un type de donnes qui peut ensuite tre


utilis dans des traitements qui ncessitent une relation d'ordre,
dans une mthode de tri par exemple :
public class Tools {
. . .

public static void sort(Comparable[] t) {


. . .

if (t[i].compareTo(t[j]) > 0)

. . .

. . .

}
. . .

}
EIA-FR / Jacques Bapst

PR1_13

18

Java / Classes abstraites et interfaces

Exemple d'interface [2]


Tous les objets dont la classe implmente l'interface Comparable
pourront ensuite tre tris.
public class Person implements Comparable {
. . .
private int age;
. . .
public int compareTo(Object p) {
if (p instanceof Person) {
if (this.age < ((Person)p).age) return -1;
if (this.age > ((Person)p).age) return 1;
return 0;
}
else . . .
}
. . .
}
. . .
Person[] population;
. . .
Tools.sort(population);
. . .
EIA-FR / Jacques Bapst

PR1_13

19

Java / Classes abstraites et interfaces

Exemple d'interface [3]


Supposons que nous voulions que les classes drives de
la classe Shape disposent toutes d'une mthode print()
permettant d'imprimer les formes gomtriques.
Il serait naturellement possible d'ajouter une mthode abstraite
print() la classe Shape et ainsi chacune des sous-classes
concrtes devrait implmenter cette mthode.
L'utilisateur de ces sous-classes serait ainsi sr de disposer
d'une mthode print() lui permettant d'imprimer la forme.
Avec cette solution, le problme serait rsolu pour toutes les
sous-classes de Shape, mais si d'autres classes (qui n'hritent
pas de Shape) souhaitaient galement disposer des fonctions
d'impression, elles devraient nouveau dclarer des mthodes
abstraites d'impression dans leur arborescence.
L'utilisation d'une interface permet de rsoudre ce problme de
manire plus lgante en dcouplant la fonctionnalit
d'impression de la hirarchie des classes.
EIA-FR / Jacques Bapst

PR1_13

20

Java / Classes abstraites et interfaces

Exemple d'interface [4]


Au lieu d'ajouter une mthode abstraite print() dans la classe
Shape nous crons une interface nomme Printable qui dfinit la
mthode abstraite print() :
public interface Printable {
public void print();
}

Et nous dclarons que la classe Shape implmente l'interface


Printable (le corps de la classe Shape reste inchang) :
public abstract class Shape implements Printable {
public abstract double perimeter(); // Mthode abstraite
public abstract double area();
// Mthode abstraite
}

EIA-FR / Jacques Bapst

PR1_13

21

Java / Classes abstraites et interfaces

Exemple d'interface [5]


Chaque sous-classe concrte de Shape devra obligatoirement
implmenter le corps de la mthode print() (en plus des mthodes
abstraites perimeter() et area()) :
//---------------------------------------------------------// Circle
//---------------------------------------------------------public class Circle extends Shape {
public static final double PI = 3.14159265358979;
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getRadius() { return radius; }
public double perimeter() { return 2*PI*radius; }
public double area()

{ return PI*radius*radius; }

public void print() { ... }


}
EIA-FR / Jacques Bapst

PR1_13

22

Java / Classes abstraites et interfaces

Exemple d'interface [6]


L'implmentation des sous-classes de Shape s'effectue donc de la
mme manire que si la mthode print() avait t dclare
comme mthode abstraite dans Shape.
L'avantage de l'interface Printable rside dans le fait qu'elle peut
tre utilise avec d'autres classes qui n'ont rien voir avec la
classe Shape :
public class Book extends Document implements Printable {
...
}

Un autre avantage est que l'interface Printable peut tre


utilise en combinaison avec d'autres interfaces, ce qui n'est pas
possible avec les classes (car une sous-classe ne peut pas avoir
plusieurs super-classes).
public class Book extends Document
implements Printable, Zoomable {
...
}
EIA-FR / Jacques Bapst

PR1_13

23

Java / Classes abstraites et interfaces

Interface fonctionnelle
Une interface fonctionnelle est une interface comprenant
exactement une mthode abstraite.
Une interface fonctionnelle peut malgr tout comporter des
constantes, des mthodes avec une implmentation par dfaut, des
mthodes redclarant certaines mthodes de la classe Object ainsi
que des mthodes statiques.
La notion d'interface fonctionnelle joue un rle important en lien
avec l'utilisation des expressions Lambda.
L'annotation @FunctionalInterface peut prcder la dclaration
des interfaces fonctionnelles. Ainsi, le compilateur vrifiera que les
rgles nonces soient respectes.
@FunctionalInterface
public interface SimpleFuncInterface {
public void doWork();
}

EIA-FR / Jacques Bapst

PR1_13

24

Java / Classes abstraites et interfaces

Classe abstraite ou interface ?


Lors de la conception d'une application ou d'une librairie, le choix
conceptuel entre une classe abstraite et une interface n'est pas
toujours facile.
Parmi les points prendre en considration, on peut rappeler
que :
Une classe peut implmenter plusieurs interfaces mais ne peut
hriter que d'une seule classe abstraite.
Une interface peut tre implmente par une classe sans qu'il y ait
de rapports troits entre les deux. Une sous-classe est lie par une
relation plus forte ("Est un ..." ).
Les classes abstraites et les interfaces permettent de dfinir des
implmentation par dfaut pour les mthodes.
Les interfaces fonctionnelles (une seule mthode abstraite) peuvent
tre implmentes par des expressions Lambdas ou des rfrences
de mthodes permettant ainsi d'allger le code.

EIA-FR / Jacques Bapst

PR1_13

25

Java / Classes abstraites et interfaces

Extension des interfaces


Les interfaces peuvent avoir des sous-interfaces (tout comme les
classes peuvent avoir des sous-classes). Comme pour les classes, le
mot-cl extends est utilis pour crer une sous-interface.
public interface Zoomable extends Observable {...}

Une sous-interface hrite de toutes les mthodes et de toutes les


constantes de son interface parente et peut dfinir de nouvelles
mthodes ainsi que de nouvelles constantes.
Contrairement aux classes, une interface peut possder plusieurs
interfaces parentes (hritage multiple).
public interface Transformable
extends Scalable, Translatable, Rotatable {...}

Une classe qui implmente une sous-interface doit implmenter


les mthodes abstraites dfinies directement par l'interface ainsi
que les mthodes abstraites hrites de toutes les interfaces
parentes de la sous-interface.
EIA-FR / Jacques Bapst

PR1_13

26

Java / Classes abstraites et interfaces

Gestion des exceptions


Les mthodes concrtes ne peuvent pas annoncer plus
d'exceptions contrles dans leurs clauses throws, que celles
qui sont annonces dans la dclaration des mthodes abstraites
qu'elles implmentent (dclaration dans classe abstraite ou interface).
public interface Writable {
public void write(Object o) throws IOException, MemOverflow;
}
public class Buffer implements Writable {
public void write(Object o) throws MemOverflow,
ArithmeticException

}
}

La mthode concrte write() n'a pas l'obligation d'annoncer toutes les exceptions
dfinies dans l'interface Writable (on ne peut pas imposer une liste d'exceptions) .
Elle ne peut pas annoncer d'exceptions contrles supplmentaires mais peut ajouter
des exceptions non-contrles (comme ArithmeticException par exemple).
EIA-FR / Jacques Bapst

PR1_13

27

Java / Classes abstraites et interfaces

Conflits de noms [1]


Des conflits de noms (collision) peuvent se produire lorsqu'une
classe implmente plusieurs interfaces comportant des noms de
mthodes ou de constantes identiques.
Il faut distinguer plusieurs situations :
Plusieurs mthodes portent des signatures identiques :
Pas de problme, la classe doit implmenter cette mthode

Mmes noms de mthodes mais profils de paramtres diffrents :


Implmentation de deux ou plusieurs mthodes surcharges

Mmes noms de mthodes, profils de paramtres identiques, mais


types des valeurs de retour diffrents :
Pas possible d'implmenter les deux interfaces (cela provoquera une
erreur la compilation : Interface-Collision)

Seulement les listes d'exceptions sont diffrentes :


La mthode ne peut pas gnrer plus d'exceptions contrles que celles
correspondant l'intersection de l'ensemble des clauses d'exception

EIA-FR / Jacques Bapst

PR1_13

28

Java / Classes abstraites et interfaces

Conflits de noms [2]


Noms de constantes identiques dans plusieurs interfaces :
Doivent tre accdes en utilisant la notation qualifie (Interface.Constante)

Plusieurs mthodes portent des signatures identiques mais ont des


implmentations par dfaut diffrentes :
Erreur dtecte par le compilateur
Obligation de redfinir la mthode en conflit dans la classe qui
implmente les interfaces
Les mthodes par dfaut peuvent malgr tout tre invoque avec la
syntaxe Interface.super.Mthode

EIA-FR / Jacques Bapst

PR1_13

29

Java / Classes abstraites et interfaces

Interface de marquage
Il est parfois utile de dfinir une interface entirement vide
appele interface de marquage.
Une classe peut implmenter cette interface en la nommant dans
la clause implements sans avoir implmenter de mthodes.
Dans ce cas, toutes les instances de la classe deviennent des
instances valables de l'interface. Il est donc possible de tester
si un objet implmente l'interface de marquage l'aide de
l'oprateur instanceof :
if (obj instanceof Cloneable) {...}

Une interface de marquage sert communiquer aux instances


qui l'implmentent des informations supplmentaires
concernant l'objet, son comportement, son implmentation,
Les interfaces java.lang.Cloneable et java.io.Serializable
constituent deux exemples d'interfaces de marquage de la plateforme Java.
EIA-FR / Jacques Bapst

PR1_13

30