Quand dois-je utiliser une interface en java? [fermé]


Un bon exemple de quand exactement utiliser des interfaces spécifiquement en Java serait idéal et toutes les décisions spécifiques qui s'appliquent.

Author: TylerH, 2010-04-06

12 answers

Utilisez les interfaces pour définir un contrat de programmation d'application (blueprint, interface) que les fournisseurs "tiers" doivent respecter et implémenter pleinement. De cette façon, les utilisateurs finaux peuvent simplement coder contre le contrat API et basculer facilement de l'implémentation concrète "sous les hottes" sans changer le code.

L'API JDBC est un excellent exemple. Il existe presque uniquement des interfaces. Les implémentations concrètes sont fournies en tant que"pilotes JDBC". Cela vous permet d'écrire tous les Code JDBC indépendant du fournisseur de base de données (DB). Vous pouvez simplement changer le pilote JDBC sans changer de ligne de code Java (à l'exception de tout code SQL spécifique à la BASE de DONNÉES codé en dur) chaque fois que vous souhaitez changer de fournisseur de base de données.

Un autre exemple est le Java EE API, il contient également à peu près des interfaces et des classes abstraites. Les implémentations concrètes sont fournies sous forme de "serveurs d'applications Java EE", "Servletcontainers", etc., tels que Sun Glassfish, Apache Tomcat, etc. Cela vous permet de vous pour déployer l'application Web (WAR) sur le serveur Web Java que vous aimez.

 31
Author: BalusC, 2015-05-20 10:51:37

Un bon endroit pour regarder serait le cadre des collections.

java.util.List //interface

java.util.ArrayList //Concrete class
java.util.LinkedList //Concrete class

Vous pouvez donc écrire du code comme ceci:

List l = new ArrayList();

l.add(..)
//do something else.

Si à l'avenir vous voulez changer l'implémentation avec disons LinkedList ou que vous possédez AwesomeList which implements List interface, tout ce que vous avez à faire est de changer la toute première ligne en:

List l = new MyAwesomeList();
or
List l = new LinkedList();

Le reste du code suivrait.

 50
Author: coolest_head, 2010-04-06 16:22:53

Des interfaces sont nécessaires là où vous attendez de la volatilité dans votre programme, des points où vous anticipez des changements, des points où votre conception doit se plier.

L'implémentation est fragile en ce sens: elle se casse assez facilement. C'est pourquoi le sous-classement n'est pas toujours la meilleure solution, tout comme les méthodes à long terme qui implémentent un comportement compliqué à elles seules sont généralement une mauvaise idée.

Les interfaces sont plus flexibles et peuvent gérer beaucoup plus de stress sur la conception de votre programme que la mise en œuvre.

En introduisant des interfaces dans votre programme, vous introduisez vraiment des points de variation auxquels vous pouvez brancher différentes implémentations pour cette interface. Le but principal des interfaces est l'abstraction , découplant le "quoi" du "comment".

Une règle importante à garder à l'esprit pour le faire en toute sécurité est le principe de substitution Liskov [UncleBob, Wikipédia ]. Alors qu'un compilateur dans un langage comme Java le fera assurez-vous que syntaxiquement tout est en ordre (bon nombre de paramètres, types, ...), LSP traite de la sémantique . En bref, LSP dit que chaque implémentation d'une interface doit (aussi) se comporter correctement pour être vraiment substituable comme décrit ci-dessus.

 11
Author: eljenso, 2010-04-17 21:35:54

À Partir de la documentation d'oracle page

Envisagez d'utiliser des interfaces si:

  1. Vous vous attendez à ce que des classes non liées implémentent votre interface. Par exemple, de nombreux objets non liés peuvent implémenter une interface sérialisable.
  2. Vous souhaitez spécifier le comportement d'un type de données particulier, mais ne vous souciez pas de savoir qui implémente son comportement.
  3. Vous voulez profiter de l'héritage multiple de type.

Jetez un oeil aux questions SE connexes avec exemples de code qui ont déjà de bonnes réponses.

Est-il plus une interface que d'avoir les bonnes méthodes

Quelle est la différence entre une interface et une classe abstraite?

Comment aurais-je dû expliquer la différence entre une Interface et une classe abstraite?

 5
Author: Ravindra babu, 2017-05-23 12:26:33
 4
Author: Boris Pavlović, 2010-04-06 16:31:09

Les interfaces sont utilisées lorsque vous avez besoin de plusieurs implémentations du même comportement. Voici un exemple d'interface que les objets pourraient implémenter pour montrer qu'ils peuvent tous être sérialisés en XML.

public interface Xmlizable
{
    public String toXML();
}

Ensuite, vous pouvez simplement passer des interfaces "Xmlizables" dans des méthodes qui ne se soucient que de cette interface.

 3
Author: feeling abused and harassed, 2010-04-06 16:16:17

Jetez un oeil au tutoriel de la collection JDK àtexte de lien . Pensez aux collections. Ce qui vient à votre esprit? Il peut être commandé ou il ne peut pas être commandé et il peut avoir des doublons ou pas.

Donc Collection est une interface avec List (ordered) et Set (unordered) comme sous-interfaces. Maintenant il ya beaucoup de questions avec des Listes, devrait-il être synchronisées ou non, devrait-il être une liste liée ou pas etc. Chaque "comportement" aura ses propres interfaces/classes abstraites.

Résumé les classes sont nécessaires lorsque vous souhaitez spécifier "certains" comportements dans les collections. Par exemple, toutes les collections (ensembles/listes, etc.) peuvent avoir une représentation "toString" qui consiste simplement à itérer sur les éléments (ordonnés/ou non) et à les stringifier. Ce comportement peut être présent dans "AbstractCollection"etc.

Si vous suivez la hiérarchie des collections JDK, c'est un excellent endroit pour en apprendre davantage sur les interfaces et les classes abstraites:)

 3
Author: Kannan Ekanath, 2010-04-06 16:24:46

Fondamentalement, vous pouvez choisir entre des interfaces et des classes abstraites lorsque vous devez "laisser de côté" certains détails d'implémentation. L'interface est généralement le meilleur choix, car les classes clientes peuvent implémenter n'importe quelle quantité d'interfaces, mais elles ne peuvent avoir qu'une seule superclasse ("l'héritage est une ressource rare", comme elles le disent).

Pourquoi voudriez-vous une classe abstraite ou une interface? Parce que parfois, lorsque vous écrivez un algorithme, vous ne vous souciez pas comment une sous-étape spécifique de cela est fait, juste qu'il est fait selon une sorte de contrat. Un exemple serait l'API Collections, avec List étant une interface - généralement, lorsque vous utilisez un List, vous ne vous souciez pas vraiment s'il enregistre des choses dans un tableau, ou dans une liste chaînée de nœuds, ou d'une autre manière. Tant qu'il stocke les trucs que vous mettez dans l'ordre que vous les mettre là, vous êtes heureux.

Alors nous avons AbstractList: Une classe abstraite implémentant List, qui fournit implémentation de presque tout ce dont un List à part entière a besoin-pour créer votre propre implémentation List, il vous suffit d'étendre AbstractList et de remplir quelques méthodes. C'est un excellent exemple de lorsqu'une classe abstraite est un bon choix - lorsque vous voulez fournir une implémentation presque complète de quelque chose, qui ne manque que quelques lacunes qui doivent être comblées par le code client.

Astuce: Si vous créez une classe abstraite contenant uniquement des méthodes abstraites, vous devriez probablement en faire une interface.

 3
Author: gustafc, 2010-04-06 16:53:41

Cette réponse est essentiellement la même que celle de coolest_head, juste un peu plus explicite pour transmettre l'utilité.

Comme l'explique coolest_head, les interfaces sont utiles lorsque vous voudrez peut-être changer les sous-composants possibles de votre programme à l'avenir. Ils vous permettent également de séparer plus facilement les préoccupations des différentes parties de la structure de votre programme, car avec les interfaces, vous pouvez vous assurer que certaines classes non liées, etc. ne sont tout simplement pas visibles pour les autres parties du programme.

Par exemple, supposons que vous voulez lire des données arbitraires et les imprimer, comme ceci:

SomeReader someReader = new SomeReader();
String data = someReader.readLine();
System.out.println(data);

Rien de chic ici, non? Mais, bien que cet exemple soit simple, il est déjà lié à la classe SomeReader, ce qui signifie que toutes les modifications que vous apportez à cette classe doivent être propagées à la classe où vous utilisez la classe - surtout si vous refactorisez certaines parties internes! Au lieu de cela, vous voulez faire ceci

IMyReader reader = new SomeReader();
System.out.println(reader.readLine());

Vous y êtes presque-maintenant le code d'impression ne le fait pas attention à l'implémentation spécifique plus, seulement sur les parties qui sont exposées par l'interface. C'est généralement suffisant car maintenant vous pouvez simplement changer cette instruction new et vous obtenez de nouvelles implémentations et tout ce qui fonctionne toujours comme prévu (tant que le contrat de l'interface est respecté parmi les classes d'implémentation!). Ceci est particulièrement pratique lorsque vous finissez par utiliser cet objet spécifique plusieurs fois-ici, je ne l'utilise qu'une seule fois mais vraiment, si vous travaillez avec par exemple des listes, combien d'opérations vous faites habituellement la même liste?

Donc, pour vraiment faire exploser cet exemple, voici à quoi votre code peut ressembler

public class RowPrinter {

    private final IMyReader reader;

    public RowPrinter(IMyReader reader) {
        this.reader = reader;
    }

    public void print() {
        IMyReader reader = getReader();
        System.out.println(reader.readLine());
    }

    protected IMyReader getReader() {
        return reader;
    }
}

Remarquez cette partie avec le constructeur? C'est inversion de contrôle et laissez-moi juste vous dire, c'est un morceau cool de génie logiciel juste là. Je peux parler d'expérience, cela vous aide avec beaucoup de tracas, que ce soit le passage d'un produit de base de données à un autre ou rendre certaines parties du thread de code sûres. Ou peut-être que vous voulez juste ajouter une couche de journalisation à une classe, facilement faisable avec un wrapping decorator qui arrive à implémenter la même interface que la classe encapsulée. Et ce n'est que le début.

Les interfaces apportent de nombreux avantages qui ne sont généralement pas évidents à partir d'exemples simples, bien que les exemples simples vous permettent de fonctionner correctement. Alors que les interfaces en Java sont une construction de langage, elles sont en fait plus paradigme de programmation plus qu'une simple fonctionnalité d'un seul langage, dans certains langages, l'émulation d'interfaces est vraiment bénéfique si vous trouvez la bonne façon de le faire.

 3
Author: Esko, 2010-04-17 21:02:10

Un principe de base de la POO est la dissimulation d'informations: masquer les détails de l'implémentation et afficher uniquement une description des services de base à l'appelant.

Java doit construire pour cet objectif: interfaces et classes abstraites. Vous pouvez définir une interface, et écrire votre code, qu'il ne dépend que de l'interface en appelant les "méthodes disponibles" qui y sont définies.

Le masquage d'informations est utilisable à la fois pour lire des classes externes (externes dans un sens qu'elles sortent du module que vous écrivez) - de cette façon, vous pouvez définir les méthodes dont vous avez besoin , et il n'est pas nécessaire d'en déduire son type d'implémentation concret -, ou lors de la définition d'un type de données utilisable en dehors de vos classes - un exemple typique pour cela est par exemple l'API de collection ou J2EE, comme

Les interfaces et les classes abstraites fournissent ces détails - mais il existe deux différences majeures: les interfaces prennent en charge l'héritage multiple, tandis que les classes abstraites peuvent contenir une implémentation de base. De maximiser leur efficacité, lors de la définition d'une interface, vous devez également définir une classe abstraite avec une implémentation par défaut significative. Si l'utilisateur de l'interface n'a pas besoin d'étendre une autre classe, il peut étendre cette classe abstraite, sinon il doit implémenter toutes les méthodes de l'interface. D'autre part, assurez-vous de ne pas lire cette classe abstraite directement, l'interface devrait être suffisante comme abstraction.

 2
Author: Zoltán Ujhelyi, 2010-04-17 20:32:19

Interfaces dans la communication à distance:

Les interfaces

Peuvent également être utilisées pour définir un "protocole" convenu pour communiquer entre différentes parties du système, éventuellement par le biais d'appels distants. Si l'interface ne définit ce qui peut être appelé, avec quels paramètres, et ce sera retourné après l'appel. Le client utilise l'interface et le serveur implémente le béton code par exemple.

Note De Côté:

En Java vous ne pouvez inherent (étendre) qu'à partir d'une classe, mais vous pouvez implémenter plus d'une interface, vous devrez donc parfois utiliser des interfaces lorsque vous avez besoin de ce type d'héritage multiple et lorsque vous décidez de ne pas utiliser la composition sur l'héritage.

 2
Author: bakkal, 2010-04-17 20:39:11

Utilisez les interfaces chaque fois que vous prévoyez de remplacer une classe d'implémentation par une autre classe à un moment donné du développement.

Je recommanderais également d'utiliser les backends d'interface pour toutes les classes dans les relations d'héritage au moins dans les projets plus sérieux: Malheureusement, je n'ai plus le lien mais un développeur du langage Java a dit un jour que l'inclusion de l'héritage de classe était la plus grande erreur dans la conception du langage.

Les arguments sont assez bons: En utilisant proper design, il est toujours possible de remplacer l'héritage de classe par l'héritage d'interface et vous gagnez beaucoup en matière de maintenance du code. Il est également plus facile de préserver les relations de type naturelles (comme par exemple from geometry ("un carré est un rectangle"-stuff) qu'avec l'héritage de classe.

 1
Author: Searles, 2010-04-06 17:52:53