Les interfaces sont le principal moyen de découpler les usages d'une classe de son implémentation.
Ce découplage apporte de la souplesse pour la maintenance de l'implémentation et favorise un comportement générique sûr du point de vue des types.
La syntaxe d'une interface est semblable à celle d'une classe, à ceci près que les méthodes n'apparaissent que sous forme de signature et qu'aucun corps n'est fourni.
public interface Language {
String speak();
}
public interface ItalianLanguage extends Language {
String speak();
String speakItalian();
}
public interface ScriptConverter {
void setVersion(String version);
String getVersion();
String convertCyrillicToLatin(String cyrillic);
}
La classe qui implémente l'interface doit implémenter toutes les opérations définies par celle-ci.
Les interfaces remplissent généralement un ou plusieurs des rôles suivants :
Comparable<T>)public class ItalianTraveller implements ItalianLanguage {
public String speak() {
return "Ciao mondo";
}
public String speakItalian() {
return speak();
}
}
public class ItalianTravellerV2 implements ItalianLanguage {
public String speak() {
return "migliorata - Ciao mondo";
}
public String speakItalian() {
return speak();
}
}
public class FrenchTraveller implements Language {
public String speak() {
return "Ça va?";
}
}
public class RussianTraveller implements Language, ScriptConverter {
private String version;
public void setVersion(String version) {
this.version = version;
}
public String getVersion() {
return version;
}
public String speak()
{
return "Привет мир";
}
public String convertCyrillicToLatin(String cyrillic) {
throw new UnsupportedOperationException();
}
}
public class DocumentTranslator implements ScriptConverter {
private String version;
public void setVersion(String version) {
this.version = version;
}
public String getVersion() {
return version;
}
public String translate(String russian) {
throw new UnsupportedOperationException();
}
public String convertCyrillicToLatin(String cyrillic) {
throw new UnsupportedOperationException();
}
}
Le code qui utilise les interfaces et les classes ci-dessus peut :
Les interfaces sont très utilisées pour faciliter les tests, car elles rendent le mocking simple.
Une interface peut étendre d'autres interfaces grâce au mot-clé extend.
Les membres d'une interface sont publics par défaut.
Les interfaces peuvent contenir des types imbriqués : interfaces, enums et classes.
Ici, les interfaces qui les contiennent jouent le rôle d'espaces de noms.
On accède aux types imbriqués depuis l'extérieur de l'interface en faisant précéder le nom du type de celui de l'interface et en utilisant la syntaxe pointée pour identifier le membre.
Par conception, Java ne prend pas en charge l'héritage multiple, mais il rend possible une forme d'héritage multiple grâce aux interfaces.
De plus, l'idée que le polymorphisme peut être implémenté au moyen des interfaces sous-tend le mécanisme des interfaces.