Interfaces Java expliquées avec des exemples

Interfaces

L'interface en Java est un peu comme la classe, mais avec une différence significative: une interfacene peut avoir que des signatures de méthode, des champs et des méthodes par défaut. Depuis Java 8, vous pouvez également créer des méthodes par défaut. Dans le bloc suivant, vous pouvez voir un exemple d'interface:

public interface Vehicle { public String licensePlate = ""; public float maxVel public void start(); public void stop(); default void blowHorn(){ System.out.println("Blowing horn"); } }

L'interface ci-dessus contient deux champs, deux méthodes et une méthode par défaut. Seul, ce n'est pas d'une grande utilité, mais ils sont généralement utilisés avec les classes. Comment? Simple, vous devez vous assurer de la classe implements.

public class Car implements Vehicle { public void start() { System.out.println("starting engine..."); } public void stop() { System.out.println("stopping engine..."); } }

Maintenant, il y a une règle de base : la classe doit implémenter toutes les méthodes de l'interface. Les méthodes doivent avoir exactement la même signature (nom, paramètres et exceptions) que celle décrite dans l'interface. Cependant, la classe n'a pas besoin de déclarer les champs, uniquement les méthodes.

Instances d'une interface

Une fois que vous avez créé une classe Java avec implementsn'importe quelle interface, l'instance d'objet peut être référencée en tant qu'instance de l'interface. Ce concept est similaire à celui de l'instanciation d'héritage.

// following our previous example Vehicle tesla = new Car(); tesla.start(); // starting engine ...

Une interface ne peut pas contenir de méthodes de constructeur. Par conséquent, vous ne pouvez pas créer une instance d'une interface elle-même. Vous devez créer une instance d'une classe implémentant une interface pour la référencer.

Considérez les interfaces comme un formulaire de contrat vierge ou un modèle.

Que pouvez-vous faire avec cette fonctionnalité? Polymorphisme! Vous ne pouvez utiliser que des interfaces pour faire référence aux instances d'objet!

class Truck implements Vehicle { public void start() { System.out.println("starting truck engine..."); } public void stop() { System.out.println("stopping truck engine..."); } } class Starter { // static method, can be called without instantiating the class public static void startEngine(Vehicle vehicle) { vehicle.start(); } } Vehicle tesla = new Car(); Vehicle tata = new Truck(); Starter.startEngine(tesla); // starting engine ... Starter.startEngine(tata); // starting truck engine ...

Mais qu'en est-il de plusieurs interfaces?

Oui, vous pouvez implémenter plusieurs interfaces dans une seule classe. Alors que dans l'héritage dans les classes, vous étiez limité à hériter d'une seule classe, vous pouvez étendre ici n'importe quel nombre d'interfaces. Mais n'oubliez pas d'implémenter toutes les méthodes de toutes les interfaces, sinon la compilation échouera!

public interface GPS { public void getCoordinates(); } public interface Radio { public void startRadio(); public void stopRadio(); } public class Smartphone implements GPS,Radio { public void getCoordinates() { // return some coordinates } public void startRadio() { // start Radio } public void stopRadio() { // stop Radio } }

Quelques fonctionnalités des interfaces

  • Vous pouvez placer des variables dans une interface, bien que ce ne soit pas une décision judicieuse car les classes ne sont pas obligées d'avoir la même variable. Bref, évitez de placer des variables!
  • Toutes les variables et méthodes d'une interface sont publiques, même si vous omettez le publicmot - clé.
  • Une interface ne peut pas spécifier l'implémentation d'une méthode particulière. C'est aux classes de le faire. Bien qu'il y ait eu une exception récente (voir ci-dessous).
  • Si une classe implémente plusieurs interfaces, il existe une faible chance de chevauchement des signatures de méthode. Étant donné que Java n'autorise pas plusieurs méthodes de la même signature, cela peut entraîner des problèmes. Voir cette question pour plus d'informations.

Méthodes par défaut de l'interface

Avant Java 8, nous n'avions aucun moyen de diriger une interface vers une implémentation de méthode particulière. Cela entraîne beaucoup de confusion et des ruptures de code si une définition d'interface est soudainement modifiée.

Supposons que vous ayez écrit une bibliothèque open source, qui contient une interface. Disons que vos clients, c'est-à-dire pratiquement tous les développeurs du monde entier, l'utilisent énormément et sont heureux. Vous avez maintenant dû mettre à niveau la bibliothèque en ajoutant une nouvelle définition de méthode à l'interface pour prendre en charge une nouvelle fonctionnalité. Mais cela briserait toutes les versions puisque toutes les classes implémentant cette interface doivent changer maintenant. Quelle catastrophe!

Heureusement, Java 8 nous fournit désormais des defaultméthodes pour les interfaces. Une defaultméthode peut contenir sa propre implémentation directement dans l'interface! Ainsi, si une classe n'implémente pas de méthode par défaut, le compilateur prendra l'implémentation mentionnée dans l'interface. Nice, n'est-ce pas? Ainsi, dans votre bibliothèque, vous pouvez ajouter n'importe quel nombre de méthodes par défaut dans les interfaces sans craindre de casser quoi que ce soit!

public interface GPS { public void getCoordinates(); default public void getRoughCoordinates() { // implementation to return coordinates from rough sources // such as wifi & mobile System.out.println("Fetching rough coordinates..."); } } public interface Radio { public void startRadio(); public void stopRadio(); } public class Smartphone implements GPS,Radio { public void getCoordinates() { // return some coordinates } public void startRadio() { // start Radio } public void stopRadio() { // stop Radio } // no implementation of getRoughCoordinates() } Smartphone motoG = new Smartphone(); motog.getRoughCoordinates(); // Fetching rough coordinates...

Mais que se passe-t-il si deux interfaces ont la même signature de méthode?

Super question. Dans ce cas, si vous ne fournissez pas l'implémentation dans la classe, un mauvais compilateur sera confus et échouera tout simplement! Vous devez également fournir une implémentation de méthode par défaut dans la classe. Il existe également une manière astucieuse superd'appeler l'implémentation que vous aimez:

public interface Radio { // public void startRadio(); // public void stopRadio(); default public void next() { System.out.println("Next from Radio"); } } public interface MusicPlayer { // public void start(); // public void pause(); // public void stop(); default public void next() { System.out.println("Next from MusicPlayer"); } } public class Smartphone implements Radio, MusicPlayer { public void next() { // Suppose you want to call MusicPlayer next MusicPlayer.super.next(); } } Smartphone motoG = new Smartphone(); motoG.next(); // Next from MusicPlayer

Méthodes statiques dans les interfaces

Autre nouveauté de Java 8, la possibilité d'ajouter des méthodes statiques aux interfaces. Les méthodes statiques dans les interfaces sont presque identiques aux méthodes statiques dans les classes concrètes. La seule grande différence est que les staticméthodes ne sont pas héritées dans les classes qui implémentent l'interface. Cela signifie que l'interface est référencée lors de l'appel de la méthode statique et non de la classe qui l'implémente.

interface MusicPlayer { public static void commercial(String sponsor) { System.out.println("Now for a message brought to you by " + sponsor); } public void play(); } class Smartphone implements MusicPlayer { public void play() { System.out.println("Playing from smartphone"); } } class Main { public static void main(String[] args) { Smartphone motoG = new Smartphone(); MusicPlayer.commercial("Motorola"); // Called on interface not on implementing class // motoG.commercial("Motorola"); // This would cause a compilation error } }

Hériter d'une interface

Il est également possible en Java pour une Interface d' hériter d' une autre Interface, en utilisant, vous l'avez deviné, le extendsmot clé:

public interface Player { public void start(); public void pause(); public void stop(); } public interface MusicPlayer extends Player { default public void next() { System.out.println("Next from MusicPlayer"); } }

Cela signifie que l' MusicPlayerinterface d' implémentation de classe doit implémenter toutes les méthodes de MusicPlayerainsi que Player:

public class SmartPhone implements MusicPlayer { public void start() { System.out.println("start"); } public void stop() { System.out.println("stop"); } public void pause() { System.out.println("pause"); } }

Vous avez donc maintenant une bonne maîtrise des interfaces Java! Découvrez les classes abstraites pour voir comment Java vous offre une autre façon de définir des contrats.