92 votes

Pourquoi aucune méthode statique dans les interfaces, mais des champs statiques et des classes internes OK? [avant Java8]

Il y a eu quelques questions posées ici sur pourquoi vous ne pouvez pas définir de méthodes statiques dans les interfaces, mais aucune d'entre elles n'aborde une incohérence fondamentale : pourquoi peut-on définir des champs statiques et des types internes statiques dans une interface, mais pas des méthodes statiques ?

Les types internes statiques ne sont peut-être pas une comparaison équitable, car il s'agit simplement de sucre syntaxique qui génère une nouvelle classe, mais pourquoi des champs mais pas des méthodes ?

Un argument contre les méthodes statiques dans les interfaces est que cela casse la stratégie de résolution de la table virtuelle utilisée par la JVM, mais cela ne devrait-il pas s'appliquer de manière égale aux champs statiques, c'est-à-dire que le compilateur peut simplement l'incorporer ?

La cohérence est ce que je recherche, et Java aurait dû soit ne pas supporter de statiques sous aucune forme dans une interface, soit être cohérent et les autoriser.

0 votes

Les champs sont définis alors que la méthode n'a pas de corps. Tenter d'appeler la méthode provoquera une erreur, tandis que les variables seront toujours présentes : qu'elles soient par défaut ou définies.

1 votes

bugs.sun.com/view_bug.do?bug_id=4093687 - fermé ne sera pas fixé avec plus de 200 votes, et c'était en 1997...

0 votes

@erickson - pourquoi dis-tu que c'est une réponse échouant à une interview ?

1voto

MetroidFan2002 Points 11413

Les méthodes statiques sont liées à une classe. En Java, une interface n'est pas techniquement une classe, c'est un type, mais pas une classe (d'où le mot-clé implémente, et les interfaces ne s'étendent pas à Object). Parce que les interfaces ne sont pas des classes, elles ne peuvent pas avoir de méthodes statiques, car il n'y a pas de classe réelle à attacher.

Vous pouvez appeler InterfaceName.class pour obtenir l'objet de classe correspondant à l'interface, mais la classe Class indique spécifiquement qu'elle représente les classes et interfaces dans une application Java. Cependant, l'interface elle-même n'est pas traitée comme une classe, et donc vous ne pouvez pas attacher de méthode statique.

0voto

cynicalman Points 4391

Seuls les champs statiques finaux peuvent être déclarés dans une interface (tout comme les méthodes, qui sont publiques même si vous n'incluez pas le mot-clé "public", les champs statiques sont "finaux" avec ou sans le mot-clé).

Il s'agit uniquement de valeurs, et elles seront copiées littéralement partout où elles sont utilisées au moment de la compilation, vous n'appelez jamais réellement les champs statiques à l'exécution. Avoir une méthode statique n'aurait pas la même sémantique, car cela impliquerait d'appeler une interface sans implémentation, ce que Java n'autorise pas.

0voto

laz Points 12212

La raison est que toutes les méthodes définies dans une interface sont abstraites que vous déclariez ou non ce modificateur explicitement. Une méthode statique abstraite n'est pas une combinaison autorisée de modificateurs puisque les méthodes statiques ne peuvent pas être remplacées.

Quant à savoir pourquoi les interfaces autorisent les champs statiques. J'ai l'impression que cela devrait être considéré comme une "fonctionnalité". La seule possibilité à laquelle je peux penser serait de regrouper des constantes qui intéresseraient les implémentations de l'interface.

Je suis d'accord que la cohérence aurait été une meilleure approche. Aucun membre statique ne devrait être autorisé dans une interface.

0voto

prerana gupta Points 1

Je crois que les méthodes statiques peuvent être accédées sans créer un objet et que l'interface ne permet pas de créer un objet afin de restreindre les programmeurs à utiliser les méthodes de l'interface directement plutôt que de sa classe implémentée. Mais si vous définissez une méthode statique dans une interface, vous pouvez y accéder directement sans son implémentation. Ainsi, les méthodes statiques ne sont pas autorisées dans les interfaces. Je ne pense pas que la cohérence devrait être une préoccupation.

0voto

Ashish Sharma Points 55

La méthode statique d'interface Java 1.8 est visible uniquement pour les méthodes d'interface, si nous supprimons la méthodeSta1() de la classe InterfaceExample, nous ne pourrons pas l'utiliser pour l'objet InterfaceExample. Cependant, comme d'autres méthodes statiques, nous pouvons utiliser les méthodes statiques d'interface en utilisant le nom de la classe. Par exemple, une instruction valide sera : exp1.methodSta1();

Ainsi, après avoir examiné l'exemple ci-dessous, nous pouvons dire : 1) La méthode statique d'interface Java fait partie de l'interface, nous ne pouvons pas l'utiliser pour les objets de la classe d'implémentation.

2) Les méthodes statiques d'interface Java sont bonnes pour fournir des méthodes utilitaires, par exemple la vérification de null, le tri de collections, le journal, etc.

3) La méthode statique d'interface Java nous aide à fournir une sécurité en empêchant les classes d'implémentation (InterfaceExample) de les remplacer.

4) Nous ne pouvons pas définir de méthode statique d'interface pour les méthodes de la classe Object, nous obtiendrons une erreur de compilation indiquant "Cette méthode statique ne peut pas masquer la méthode d'instance de Object". Cela n'est pas autorisé en Java, car Object est la classe de base pour toutes les classes et nous ne pouvons pas avoir une méthode statique au niveau de la classe et une autre méthode d'instance de même signature.

5) Nous pouvons utiliser les méthodes statiques d'interface Java pour supprimer les classes utilitaires telles que Collections et déplacer toutes ses méthodes statiques vers l'interface correspondante, ce qui serait facile à trouver et à utiliser.

public class InterfaceExample implements exp1 {

    @Override
    public void method() {
        System.out.println("From method()");
    }

    public static void main(String[] args) {
        new InterfaceExample().method2();
        InterfaceExample.methodSta2();      //  <---------------------------    ne compilerait pas
        // methodSta1();                        //  <---------------------------    ne compilerait pas
        exp1.methodSta1();
    }

    static void methodSta2() {          //          <-- compile avec succès mais ne peut pas être redéfini dans les classes enfants
        System.out.println("========= InterfaceExample :: de methodSta2() ======");
    }
}

interface exp1 {

    void method();
    //protected void method1();         //          <--      erreur
    //private void method2();           //          <--      erreur
    //static void methodSta1();         //          <--      erreur nécessite un corps en Java 1.8

    static void methodSta1() {          //          <-- compile avec succès mais ne peut pas être redéfini dans les classes enfants
        System.out.println("========= exp1:: de methodSta1() ======");
    }

    static void methodSta2() {          //          <-- compile avec succès mais ne peut pas être redéfini dans les classes enfants
        System.out.println("========= exp1:: de methodSta2() ======");
    }

    default void method2() { System.out.println("---  exp1:: de method2() ---");}
    //synchronized default void method3() { System.out.println("---");}             // <-- Modificateur non valide pour la méthode d'interface method3; seuls sont permis public, abstract, default, static
                                                                                    // et strictfp
    //final default void method3() { System.out.println("---");} //             <--      erreur
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X