Je viens de trouver une interface imbriquée statique dans notre base de code.
class Foo {
public static interface Bar {
/* snip */
}
/* snip */
}
Je n'avais jamais vu ça avant. Le développeur d'origine est hors de portée. Je dois donc demander à SO:
Quelle est la sémantique derrière une interface statique? Qu'est-ce qui changerait si je supprimais le static
? Pourquoi est-ce que quelqu'un ferait ça?
Réponses:
Le mot-clé statique dans l'exemple ci-dessus est redondant (une interface imbriquée est automatiquement "statique") et peut être supprimé sans aucun effet sur la sémantique; Je recommanderais qu'il soit supprimé. Il en va de même pour «public» sur les méthodes d'interface et «public final» sur les champs d'interface - les modificateurs sont redondants et ajoutent simplement de l'encombrement au code source.
Dans les deux cas, le développeur déclare simplement une interface nommée Foo.Bar. Il n'y a pas d'autre association avec la classe englobante, sauf que le code qui ne peut pas accéder à Foo ne pourra pas non plus accéder à Foo.Bar. (À partir du code source - le bytecode ou la réflexion peut accéder à Foo.Bar même si Foo est privé du package!)
Il est acceptable de créer une interface imbriquée de cette façon si vous vous attendez à ce qu'elle soit utilisée uniquement à partir de la classe externe, afin de ne pas créer de nouveau nom de niveau supérieur. Par exemple:
la source
On a répondu à la question, mais une bonne raison d'utiliser une interface imbriquée est si sa fonction est directement liée à la classe dans laquelle elle se trouve. Un bon exemple de ceci est a
Listener
. Si vous aviez une classeFoo
et que vous vouliez que d'autres classes puissent y écouter des événements, vous pourriez déclarer une interface nomméeFooListener
, ce qui est correct, mais il serait probablement plus clair de déclarer une interface imbriquée et de faire implémenter ces autres classesFoo.Listener
( une classe imbriquéeFoo.Event
n'est pas mauvaise avec cela).la source
java.util.Map.Entry
(qui est une interface imbriquée dans une autre interface).Map.Entry
) ou classes soient également dans ce package. Je dis cela parce que j'aime garder mes cours courts et précis. Un lecteur peut également voir quelles autres entités sont liées à une classe en regardant les classes dans le package. J'aurais probablement un paquetjava.collections.map
de cartes. Il s'agit d'OO et de modularité.java.util
a trop en elle.util
c'est commecommon
- une odeur OMIjava.util
certainement trop en elle. Cela dit, je ne pense pas non plus que le décomposer en paquets aussi fins que vous le suggérez soit idéal.java.util.MapEntry
dehors de son propre package. Premier réflexe: quelles sont les interfaces liées à cette classe? Je regarde dans la classe. À moins que javadoc ne lie à cette interface, je n'ai aucune idée de leur relation. De plus, les gens ne regardent pas le package d'importation. Chacun a ses propres opinions. Personne n'a raison, personne n'a tortLes interfaces membres sont implicitement statiques. Le modificateur statique de votre exemple peut être supprimé sans modifier la sémantique du code. Voir aussi la spécification du langage Java 8.5.1. Déclarations de type de membre statique
la source
Une interface interne doit être statique pour être accessible. L'interface n'est pas associée aux instances de la classe, mais à la classe elle-même, donc elle serait accessible avec
Foo.Bar
, comme ceci:Dans la plupart des cas, cela n'est pas différent d'une classe interne statique.
la source
The interface isn't associated with instances of the class, but with the class itself
plus loin, je ne l'ai pas comprisLa réponse de Jesse est proche, mais je pense qu'il existe un meilleur code pour démontrer pourquoi une interface interne peut être utile. Regardez le code ci-dessous avant de continuer. Pouvez-vous trouver pourquoi l'interface interne est utile? La réponse est que la classe DoSomethingAlready peut être instanciée avec n'importe quelle classe qui implémente A et C; pas seulement le zoo de la classe concrète. Bien sûr, cela peut être réalisé même si AC n'est pas intérieur, mais imaginez concaténer des noms plus longs (pas seulement A et C), et le faire pour d'autres combinaisons (disons, A et B, C et B, etc.) et vous facilement voir comment les choses deviennent hors de contrôle. Sans oublier que les personnes qui examinent votre arbre source seront submergées par des interfaces qui n'ont de sens que dans une seule classe.une interface interne permet la construction de types personnalisés et améliore leur encapsulation .
la source
Zoo
n'implémente pas l'interfaceAC
, par conséquent, les instances deZoo
ne peuvent pas être passées au constructeurDoSomethingAlready
dont elles attendentAC
. Le fait que celaAC
s'étende à la fois,A
etC
, n'implique pas que les classes implémentantA
etC
implémentent aussi par magieAC
.Pour répondre très directement à votre question, consultez Map.Entry.
Map.Entry
cela peut aussi être utile
Entrée de blog Inerfaces imbriquées statiques
la source
En général, je vois des classes internes statiques. Les classes internes statiques ne peuvent pas référencer les classes contenant, contrairement aux classes non statiques. À moins que vous ne rencontriez des collisions de packages (il existe déjà une interface appelée Bar dans le même package que Foo), je pense que je ferais de son propre fichier. Cela pourrait également être une décision de conception d'imposer la connexion logique entre Foo et Bar. L'auteur a peut-être voulu que Bar ne soit utilisé qu'avec Foo (bien qu'une interface interne statique ne l'impose pas, juste une connexion logique)
la source
Si vous changez la classe Foo en interface Foo, le mot-clé "public" dans l'exemple ci-dessus sera également redondant car
la source
En 1998, Philip Wadler a suggéré une différence entre les interfaces statiques et les interfaces non statiques.
Par exemple, il a proposé une solution au problème de l' expression , qui est l'inadéquation entre l'expression comme «combien votre langue peut-elle exprimer» d'une part et l'expression comme «les termes que vous essayez de représenter dans votre langue» d'autre part .
Un exemple de la différence entre les interfaces imbriquées statiques et non statiques peut être vu dans son exemple de code :
Sa suggestion ne l'a jamais fait en Java 1.5.0. Par conséquent, toutes les autres réponses sont correctes: il n'y a aucune différence entre les interfaces imbriquées statiques et non statiques.
la source
En Java, l'interface / classe statique permet à l'interface / classe d'être utilisée comme une classe de niveau supérieur, c'est-à-dire qu'elle peut être déclarée par d'autres classes. Vous pouvez donc faire:
Sans la statique, ce qui précède ne pourrait pas être compilé. L'avantage est que vous n'avez pas besoin d'un nouveau fichier source juste pour déclarer l'interface. Il associe également visuellement l'interface Bar à la classe Foo puisque vous devez écrire Foo.Bar et implique que la classe Foo fait quelque chose avec les instances de Foo.Bar.
Une description des types de classe en Java .
la source
Statique signifie que n'importe quelle partie de classe du package (projet) peut y accéder sans utiliser de pointeur. Cela peut être utile ou gênant selon la situation.
L'exemple parfait de l'utilité des méthodes "statiques" est la classe Math. Toutes les méthodes en mathématiques sont statiques. Cela signifie que vous n'avez pas à vous déplacer, créer une nouvelle instance, déclarer des variables et les stocker dans encore plus de variables, vous pouvez simplement entrer vos données et obtenir un résultat.
La statique n'est pas toujours aussi utile. Si vous effectuez une comparaison de cas par exemple, vous souhaiterez peut-être stocker des données de plusieurs manières différentes. Vous ne pouvez pas créer trois méthodes statiques avec des signatures identiques. Vous avez besoin de 3 instances différentes, non statiques, puis vous pouvez comparer, car si elles sont statiques, les données ne changeront pas avec l'entrée.
Les méthodes statiques sont bonnes pour les retours ponctuels et les calculs rapides ou les données faciles à obtenir.
la source