Vous êtes sur la page 1sur 12

Cours Java : Les Classes Abstraites et les Interfaces

Chapitre 8 - Les Classes Abstraites et Les Interfaces


I. Les Classes abstraites :
a. Introduction :

Une classe abstraite est quasiment identique à une classe normale. Cela dit, elle a tout
de même une particularité : vous ne pouvez pas l'instancier !
C’est une classe qu’on ne peut pas directement instancier car certaines de ses méthodes ne sont
pas implémentées. Une classe abstraite peut donc contenir des variables, des méthodes
implémentées et des signatures de méthode à implémenter
Imaginons que nous ayons une classe A déclarée abstraite. Voici un code qui ne
compilera pas :

public class Test


{
public static void main(String[] args)
{
A obj = new A(); //Erreur de compilation !
}
}
Remarque :
• Les classes abstraites sont déclarées par le modificateur abstract utilisé devant le mot-clé
class.
• Il y a plusieurs intérêts à définir des classes abstraites :
▪ pour interdire l'instanciation d'une classe ;
▪ pour faire de la factorisation de code en ne donnant qu'une implémentation
partielle.

b. Exemple : (Réalisons un programme qui gère différents types d'animaux).


Dans ce programme, vous aurez des loups, des chiens, des chats, des lions et des tigres.
Tous ces animaux ont des points communs ! Et qui dit points communs dit héritage. Que
pouvons-nous définir de commun à tous ces animaux ? Le fait qu'ils aient une couleur, un poids,
un cri, une façon de se déplacer, qu'ils mangent et boivent quelque chose.
Nous pouvons donc créer une classe mère : appelons-la Animal. Avec ce que nous
avons dégagé de commun, nous pouvons lui définir des attributs et des méthodes. Voici donc
ce à quoi ressemblent nos classes tant qu'à présent

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 1/12


Cours Java : Les Classes Abstraites et les Interfaces

Nous avons bien notre classe mère Animal et nos animaux qui en héritent. Vu que notre
classe Animal est public, qu'est censé faire un objet Animal ? Quel est son poids, sa couleur,
que mange-t-il ?

public class Test


{
public static void main(String [] args)
{
Animal ani = new Animal();
ani.manger(); //Que doit-il manger ?
}
}
Il est bien clair que cette classe « Animal » n’est pas bonne à être instanciée! C'est là
qu'entrent en jeu nos classes abstraites. En fait, ces classes servent à définir une superclasse :
par là, vous pouvez comprendre qu'elles servent essentiellement à créer un nouveau type
d'objets. Voyons maintenant comment créer une telle classe.
En fait, il existe une règle pour qu'une classe soit considérée comme abstraite. Elle doit
être déclarée avec le mot clé abstract.

abstract class Animal{ }


Une telle classe peut contenir la même chose qu'une classe normale. Ses enfants
pourront utiliser tous ses éléments déclarés (attributs et méthodes déclarés public ou protected).
Cependant, ce type de classe permet de définir des méthodes abstraites qui présentent une
particularité : elles n'ont pas de corps ! En voici un exemple :

abstract class Animal


{
abstract void manger(); //Une méthode abstraite
}
Retenez bien qu'une méthode abstraite n'est composée que de l'en-tête de la méthode
suivie d'un point-virgule « ; ». (Difficile de voir ce que cette méthode sait faire).
Vous avez vu les avantages de l'héritage et du polymorphisme. Eh bien nos classes
enfants hériteront aussi des méthodes abstraites, mais étant donné que celles-ci n'ont pas de
corps, nos classes enfants seront obligées de redéfinir ces méthodes ! Elles présentent donc des
méthodes polymorphes.
public class Test {

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 2/12


Cours Java : Les Classes Abstraites et les Interfaces

public static void main(String args[]){


Animal loup = new Loup();
Animal chien = new Chien();
loup.manger();
chien.crier();
}
}

c. Généralisation de l’exemple :

Tout d'abord, établissons un bilan de ce que nous savons :


• Nos objets seront probablement tous de couleur et de poids différents. Nos classes
auront donc le droit de modifier ceux-ci.
• Ici, nous partons du principe que tous nos animaux mangent de la viande. La méthode
manger() sera donc définie dans la classe Animal.
• Idem pour la méthode boire(). Ils boiront tous de l'eau.
• Ils ne crieront pas et ne se déplaceront pas de la même manière. Nous emploierons donc
des méthodes polymorphes et déclarerons les méthodes deplacement() et crier()
abstraites dans la classe Animal.

La figure suivante représente le diagramme des classes de nos futurs objets. Ce


diagramme permet de voir si une classe est abstraite : son nom est alors en italique.

Nous voyons bien que notre classe Animal est déclarée abstraite et que nos classes filles
héritent de celle-ci. De plus, nos classes filles ne redéfinissent que deux méthodes sur quatre, on en
conclut donc que ces deux méthodes doivent être abstraites. Nous ajouterons deux constructeurs à nos
classes filles : un par défaut et un autre comprenant les deux paramètres d'initialisation. À cela, nous
ajouterons aussi les accesseurs d'usage. Mais il est possible aussi de faire autrement. Vu les animaux
présents, nous aurions pu faire une sous-classe Carnivore, ou encore
« AnimalDomestique» et « AnimalSauvage»… Ici, nous allons nous contenter de faire deux sous-
classes : « Canin » et « Félin », qui hériteront d'Animal et dont nos objets eux-mêmes hériteront.

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 3/12


Cours Java : Les Classes Abstraites et les Interfaces

Voici les codes java correspondants :

Animal.java

abstract class Animal {

protected String couleur;


protected int poids;

protected void manger(){


System.out.println("Je mange de la viande.");
}

protected void boire(){


System.out.println("Je bois de l'eau !");
}

abstract void deplacement();

abstract void crier();

public String toString(){


String str = "Je suis un objet de la " + this.getClass() + ", je suis " + this.couleur + ", je pèse
" + this.poids;
return str;
}
}

Felin.java

public abstract class Felin extends Animal {


void deplacement() {
System.out.println("Je me déplace seul !");
}
}

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 4/12


Cours Java : Les Classes Abstraites et les Interfaces

Canin.java

public abstract class Canin extends Animal {


void deplacement() {
System.out.println("Je me déplace en meute !");
}
}

Chien.java

public class Chien extends Canin {

public Chien(){

public Chien(String couleur, int poids){


this.couleur = couleur;
this.poids = poids;
}

void crier() {
System.out.println("J'aboie sans raison !");
}
}

Loup.java

public class Loup extends Canin {

public Loup(){

public Loup(String couleur, int poids){


this.couleur = couleur;
this.poids = poids;
}

void crier() {
System.out.println("Je hurle à la Lune en faisant ouhouh !");
}
}

Lion.java :

public class Lion extends Felin {

public Lion(){

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 5/12


Cours Java : Les Classes Abstraites et les Interfaces

public Lion(String couleur, int poids){


this.couleur = couleur;
this.poids = poids;
}

void crier() {
System.out.println("Je rugis dans la savane !");
}
}

Tigre.java :

public class Tigre extends Felin {

public Tigre(){

}
public Tigre(String couleur, int poids){
this.couleur = couleur;
this.poids = poids;
}

void crier() {
System.out.println("Je grogne très fort !");
}
}

Chat .java

public class Chat extends Felin {

public Chat(){

}
public Chat(String couleur, int poids){
this.couleur = couleur;
this.poids = poids;
}

void crier() {
System.out.println("Je miaule sur les toits !");
}
}

Programmme main() :

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 6/12


Cours Java : Les Classes Abstraites et les Interfaces

public class Test


{
public static void main(String[] args)
{
Loup l = new Loup("Gris bleuté", 20);
l.boire();
l.manger();
l.deplacement();
l.crier();
System.out.println(l.toString());
}
}

Le jeu d’essaie de ce code correspond à la figure suivante :

II. Les Interfaces :

Une interface est un type, au même titre qu’une classe, mais abstrait et qui donc ne peut
être instancié (par appel à new plus constructeur). Une interface décrit un ensemble de
signatures de méthodes, sans implémentation, qui doivent être implémentées dans toutes les
classes qui implémentent l’interface. L’utilité du concept d’interface réside dans le
regroupement de plusieurs classes, tel que chacune implémente un ensemble commun de
méthodes, sous un même type. Une interface possède les caractéristiques suivantes :

● Elle contient des signatures de méthodes ;


● Elle ne peut pas contenir de variables ;
● Une interface peut hériter d’une autre interface (avec le mot-clé extends) ;
● Une classe (abstraite ou non) peut implémenter plusieurs interfaces. La liste des interfaces
implémentées doit alors figurer après le mot-clé implements placé dans la déclaration de classe,
en séparant chaque interface par une virgule.

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 7/12


Cours Java : Les Classes Abstraites et les Interfaces

a. Exemple : L'architecture que nous avons développée avec les classes abstraites forme une
bonne base. Mais, que se passerait-il si on ajoute une contrainte qui dit que nos chiens
devront apprendre à faire de nouvelles choses telles que :
• faire le beau ;
• faire des câlins ;

1ère solution : Ajouter ces méthodes dans la classe « Animal ».

Dans ce cas vous allez vous rendre compte que vous obtiendrez des lions, des tigres, des loups
et des chats qui auront la possibilité de faire le beau ? c’est bon pour le chat mais pas possible pour les
autres.

2ème solution : Ajouter ces méthodes dans les classes « Chien » et « Chat ».

C’est possible comme solution mais si vous faites cela, adieu au polymorphisme !.

3ème solution : redéfinir un supertype pour pouvoir utiliser le polymorphisme.

Mais dans ce cas on va faire de l’héritage multiple qui est déjà interdit par java !!!
La solution consiste donc à développer un nouveau supertype et s'en servir dans nos classes
« Chien » et « Chat ». Ceci est possible grâce aux interfaces.

En fait, les interfaces permettent de créer un nouveau supertype ; on peut même en ajouter
autant que l'on le veut dans une seule classe ! Quant à l'utilisation de nos objets, la convention
est toute trouvée. Pourquoi ? Parce qu'une interface n'est rien d'autre qu'une classe 100 %
abstraite.

b. D’une manière générale :

Pour définir une interface, au lieu d'écrire :


public class A { }
Il vous suffit de faire :
public interface I { }

Vu qu'une interface est une classe 100 % abstraite, il ne reste qu'à y ajouter des méthodes
abstraites, mais sans le mot clé abstract. Voici des exemples :

public interface I{
public void A();
public String B();
}

public interface I2{


public void C();
public String D();

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 8/12


Cours Java : Les Classes Abstraites et les Interfaces

}
Et pour faire en sorte qu'une classe utilise une interface, il suffit d'utiliser le mot clé implements.
Ce qui nous donnerait :

public class X implements I{ // On dit que la classe X implémente l'interface I


public void A(){
//…
}
public String B(){
//…
}
}
Il est possible aussi qu’une classe implémente plusieurs interfaces, voilà comment ça se passe :

public class X implements I, I2{


public void A(){
//…
}
public String B(){
//…
}
public void C(){
//…
}
public String D(){
//…
}
}

c. Implémentation de l’interface pour notre exemple :

Voilà où nous en sommes :


• nous voulons que nos chiens et nos chats puissent être amicaux ;
• nous voulons définir un supertype pour utiliser le polymorphisme ;
• nous voulons pouvoir continuer à utiliser nos objets comme avant.

Nous allons créer l'interface domestique pour ensuite l'implémenter dans nos objets Chiens et
chats.

Sous NetBeans, vous pouvez faire File > New > Interface :

public interface Domestique {


public void faireCalin();

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 9/12


Cours Java : Les Classes Abstraites et les Interfaces

public void faireLeBeau();


}
À présent, il ne nous reste plus qu'à implémenter l'interface dans notre classe Chien et aussi
notre classe Chat :

public class Chien extends Canin implements Domestique {

public Chien(){

}
public Chien(String couleur, int poids){
this.couleur = couleur;
this.poids = poids;
}

void crier() {
System.out.println("J'aboie sans raison !");
}

public void faireCalin() {


System.out.println("Je te fais un GROS CÂLIN");
}

public void faireLeBeau() {


System.out.println("Je fais le beau Habhab!");
}

Celui de la classe chat :

public class Chat extends Felin implements domestique {

public Chat(){

}
public Chat(String couleur, int poids){
this.couleur = couleur;
this.poids = poids;
}

void crier() {
System.out.println("Je miaule sur les toits !");
}

public void faireCalin() {


System.out.println("Je te fais un GROS CÂLIN");
}

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 10/12


Cours Java : Les Classes Abstraites et les Interfaces

public void faireLeBeau() {


System.out.println("Je fais le beau Miaou!");
}
}

Remarque : L'ordre des déclarations est primordial. Vous devez mettre l'expression d'héritage
avant l'expression d'implémentation, sinon votre code ne compilera pas.

Voici un code que vous pouvez utiliser pour tester le polymorphisme de notre implémentation :

public class ExempleClasseAbstraite {


public static void main(String[] args) {
//Les méthodes d'un chien
Chien c = new Chien("Gris bleuté", 20);
c.boire();
c.manger();
c.deplacement();
c.crier();
System.out.println(c.toString());
System.out.println("--------------------------------------------");
//Les méthodes de l'interface
c.faireCalin();
c.faireLeBeau();
System.out.println("--------------------------------------------");
//Utilisons le polymorphisme de notre interface
Domestique r = new Chien();
r.faireLeBeau();
r.faireCalin();

//Les méthodes d'un chat


Chat h = new Chat("siamois", 7);
h.boire();
h.manger();
h.deplacement();
h.crier();
System.out.println(h.toString());
System.out.println("--------------------------------------------");
//Les méthodes de l'interface
h.faireCalin();
h.faireLeBeau();
System.out.println("--------------------------------------------");
//Utilisons le polymorphisme de notre interface
Domestique r1 = new Chat();
r1.faireLeBeau();
r1.faireCalin();

}
}

Objectif atteint ! Nous sommes parvenus à définir deux superclasses afin de les utiliser comme
supertypes et de jouir pleinement du polymorphisme.

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 11/12


Cours Java : Les Classes Abstraites et les Interfaces

Annexe :
Exemple de classe abstraite : Classe Object

En Java, la racine de l’arbre d’héritage des classes est la classe java.lang.Object. Toutes
les classes héritent de la classe Object :

- La classe Object n’a pas de variable d’instance ni de variable de classe


- La classe Object fournit plusieurs méthodes qui sont héritées par toutes les classes sans
exception (les plus couramment utilisées sont les méthodes toString() et equals()).

Classe Object – méthode toString() :

public String toString() :

• renvoie une description de l’objet sous la forme d’une chaîne de caractères


• Elle est utile pendant la mise au point des programmes pour faire afficher l’état d’un objet
• La description doit donc être concise, mais précise

Réalisé par : M. Bassem BOUGHZAlA (ISET RADES) Page 12/12

Vous aimerez peut-être aussi