« Bonjour, Amigo ! Aujourd'hui, tu vas découvrir de nouvelles choses. Le sujet du jour est, roulement de tambour, les interfaces. »

« Oui. Une si belle journée que je vais rentrer chez moi prendre un bon bain. »

Une interface est l'enfant de l'abstraction et du polymorphisme. Les interfaces sont très semblables à une classe abstraite où toutes les méthodes seraient abstraites. Elles sont déclarées de la même manière qu'une classe, mais avec le mot-clé interface. Voici quelques exemples : »

Code Description et faits
interface Drawable
{
void draw();
}
interface HasValue
{
int getValue();
}
1) Au lieu du mot-clé class, nous écrivons interface.

2) Une interface contient uniquement des méthodes abstraites (inutile d'ajouter le mot-clé abstract).

3) En fait, toutes les méthodes des interfaces sont public.

interface Element extends Drawable, HasValue
{
int getX();
int getY();
}
Une interface peut uniquement hériter d'autres interfaces.

Tu peux avoir beaucoup d'interfaces parentes.

class abstract ChessItem implements Drawable, HasValue
{
private int x, y, value;

public int getValue()
{
return value;
}

public int getX()
{
return x;
}

public int getY()
{
return y;
}

}
Une classe peut hériter de plusieurs interfaces (et d'une seule classe). Pour montrer cet héritage, nous utilisons le mot-clé implements.

La classe ChessItem  a été déclarée comme abstraite : elle implémente toutes les méthodes héritées, à l'exception de draw.

En d'autres termes, ChessItem contient une méthode abstraite : draw().

« Intéressant. Mais pourquoi avons-nous besoin des interfaces ? Quand sont-elles utilisées ? »

« Les interfaces ont deux solides avantages par rapport aux classes : »

1) La séparation des « définitions de méthode » et de leurs implémentations.

Je t'ai dit précédemment que si tu voulais autoriser les autres classes à appeler les méthodes de ta classe, tu devais les marquer avec le mot-clé public. Si tu veux être certain que les méthodes ne peuvent être appelées que depuis ta propre classe, tu dois les marquer avec le mot-clé private. En d'autres termes, nous divisons les méthodes de la classe en deux catégories : 'pour tout le monde' et 'juste pour moi'.

Nous pouvons utiliser des interfaces pour renforcer cette séparation encore plus. Nous créerons une « classe pour tout le monde » spéciale qui héritera d'une seconde « classe juste pour moi ». Voici à quoi cela ressemblerait :

Avant
class Student
{
 private String name;

 public Student(String name)
 {
  this.name = name;
 }

 public String getName()
 {
  return this.name;
 }

 private void setName(String name)
 {
  this.name = name;
 }
Après
interface Student
{
 public String getName();
}

class StudentImpl implements Student
{
 private String name;
 public StudentImpl(String name)
 {
  this.name = name;
 }
 public String getName()
 {
  return this.name;
 }
 private void setName(String name)
 {
  this.name = name;
 }
}
Avant
public static void main(String[] args)
{
 Student student =
               new Student("Alibaba");
 System.out.println(student.getName());
}
Après
public static void main(String[] args)
{
 Student student =
               new StudentImpl("Ali");
 System.out.println(student.getName());
}

Nous divisons notre classe en deux parties : une interface et une classe qui implémente l'interface.

« Alors où est l'avantage ? »

« La même interface peut être implémentée (héritée) par différentes classes. Et chaque classe peut avoir son propre comportement. Tout comme ArrayList et LinkedList sont deux implémentations différentes de l'interface List. »

Ainsi, nous cachons non seulement les différentes implémentations, mais aussi les classes qui contiennent les implémentations (nous pouvons simplement utiliser des interfaces partout dans le code). Cela nous permet de manière très flexible, à mesure que le programme progresse, de remplacer certains objets par d'autres et de modifier le comportement d'un objet à l'insu de toutes les classes qui l'utilisent.

En combinaison avec le polymorphisme, c'est une technique très puissante. À l'heure actuelle, tu ne vois sans doute pas pourquoi nous aurions besoin de le faire. Tu devras d'abord rencontrer des programmes comprenant des dizaines ou des centaines de classes pour réaliser combien les interfaces peuvent nous simplifier la vie.

2) Héritage multiple.

En Java, chaque classe ne peut avoir qu'une seule classe parente. Dans d'autres langages de programmation, les classes peuvent souvent avoir plusieurs classes parentes. C'est très pratique, mais cela crée aussi beaucoup de problèmes.

Java offre un compromis :  tu ne peux pas hériter de plusieurs classes, mais tu peux implémenter plusieurs interfaces. Une interface peut avoir plusieurs interfaces parentes. Une classe peut implémenter plusieurs interfaces et hériter d'une seule classe parente.