Pourquoi les variables d'interface sont-elles statiques et finales par défaut?


274

Pourquoi les variables d'interface sont-elles statiques et finales par défaut en Java?


41
Vous ne devez pas placer de variables dans les interfaces.
cherouvim

34
Parce que les interfaces définissent des contrats qui peuvent être mis en œuvre de différentes manières. La valeur d'une variable est l'implémentation.
cherouvim

10
Nous pouvons certainement quand nous savons que toutes les classes implémentant l'interface ont des variables constantes (noms de champs par exemple).
Aniket Thakur

Est-ce une bonne idée de faire d'une variable dans une classe une instance de l'interface que la classe implémente? J'ai déjà entendu cela.
Doug Hauf

Les interfaces en java suivent le principe ACID, final en raison de la normalisation en C. @cherouvim Le type d'une variable est l'implémentation, une variable doit être déclarée, avec ou sans valeur et la définition d'une variable est la valeur. Si vous modifiez la valeur d'une variable n'est pas une réimplémentation, sa redéfinition.
Grim

Réponses:


264

D'après la FAQ de conception d'interface Java de Philip Shaw:

Les variables d'interface sont statiques car les interfaces Java ne peuvent pas être instanciées à part entière; la valeur de la variable doit être affectée dans un contexte statique dans lequel aucune instance n'existe. Le dernier modificateur garantit que la valeur affectée à la variable d'interface est une vraie constante qui ne peut pas être réaffectée par le code de programme.

la source


39
Notez que les classes abstraites ne peuvent pas non plus être instanciées «à part entière» et qu'elles peuvent avoir des variables d'instance.
macias

18
Cette explication du staticmodificateur est complètement fausse. Les variables d'instance publique d'une classe font partie de son interface et il n'y a aucune raison pour qu'elles ne soient pas abstraites dans un Java interface, tout comme les méthodes d'instance. Peu importe qu'un Java interfacene puisse pas être instancié directement - vous pouvez toujours avoir des instances de classes qui implémentent le interfaceet il est judicieux d'exiger qu'elles aient une certaine variable d'instance publique. Quant à la partie sur final, cela n'offre aucune explication - elle décrit simplement ce que finalsignifie.
pyrocrastie

3
La citation ci-dessus est meilleure dans son contexte. La raison qu'il donne est que "les variables d'interface sont destinées à être des constantes Java". La citation expliquait simplement pourquoi une telle constante serait statique et définitive. C'est vrai, mais la vraie question est: pourquoi les variables ne sont-elles pas autorisées dans le cadre de l' interface réelle (c'est-à-dire en spécifiant les noms et les types de membres non privés qui doivent apparaître dans une classe d'implémentation). S'ils voulaient des "constantes d'interface" spéciales, ils auraient pu utiliser une nouvelle syntaxe ou simplement décider que toutes les variables réellement définies dans une interface sont des constantes d'interface.
pyrocrastie

6
Les interfaces ne peuvent pas avoir de variables d'instance afin d'éviter l'héritage multiple des problèmes d'état. Voir docs.oracle.com/javase/tutorial/java/IandI/… . Une classe ne peut pas étendre plus d'une classe pour la même raison.
denis

1
Comment les méthodes par défaut sont-elles introduites et ont-elles une instance, mais la variable d'instance n'est pas prise en charge ...
M.kazem Akhgary

41

Puisque l'interface n'a pas d'objet direct, la seule façon d'y accéder est d'utiliser une classe / interface et c'est pourquoi, si une variable d'interface existe, elle doit être statique sinon elle ne sera pas du tout accessible au monde extérieur. Maintenant qu'il est statique, il ne peut contenir qu'une seule valeur et toutes les classes qui l'implémentent peuvent la changer et donc ce sera tout le bordel.

Par conséquent, s'il existe une variable d'interface, elle sera implicitement statique, finale et évidemment publique !!!


Bien sûr, une variable d'instance serait accessible si elle était autorisée dans un Java interface. Une classe implémenterait l'interface, déclarant la variable d'instance (comme requis par l'interface). Son constructeur (ou une autre méthode) définit la variable d'instance. Lorsqu'une instance de la classe est instanciée, vous pourrez accéder à sa variable d'instance.
pyrocrastie

Java permet aux méthodes statiques avec corps d'exister dans une interface. Ceux-ci pourraient accéder aux variables statiques. Ils ne peuvent tout simplement pas les modifier, ce qui signifie que les fonctions statiques ne peuvent pas stocker de données
simpleuser

36

public : pour l'accessibilité dans toutes les classes, tout comme les méthodes présentes dans l'interface

statique : comme l'interface ne peut pas avoir d'objet, interfaceName.variableName peut être utilisé pour le référencer ou directement le variableName dans la classe qui l'implémente.

final : pour en faire des constantes. Si 2 classes implémentent la même interface et que vous leur donnez le droit de modifier la valeur, un conflit se produira dans la valeur actuelle de la var, c'est pourquoi une seule initialisation est autorisée.

De plus, tous ces modificateurs sont implicites pour une interface, vous n'avez pas vraiment besoin d'en spécifier aucun.


15

( Ce n'est pas une réponse philosophique mais plutôt une réponse pratique ). L'exigence d'un staticmodificateur est évidente, ce à quoi d'autres ont répondu. Fondamentalement, comme les interfaces ne peuvent pas être instanciées, la seule façon d'accéder à ses champs est d'en faire un champ de classe - static.

La raison pour laquelle les interfacechamps deviennent automatiquement final(constants) est d'empêcher différentes implémentations de modifier accidentellement la valeur de la variable d'interface, ce qui peut affecter par inadvertance le comportement des autres implémentations. Imaginez le scénario ci-dessous où une interfacepropriété n'est pas devenue explicitement finalpar Java:

public interface Actionable {
    public static boolean isActionable = false;

    public void performAction();
}

public NuclearAction implements Actionable {

    public void performAction() {
        // Code that depends on isActionable variable
        if (isActionable) {
            // Launch nuclear weapon!!!
        }
    }
}

Maintenant, pensez à ce qui se passerait si une autre classe qui implémente Actionablemodifie l'état de la variable d'interface:

public CleanAction implements Actionable  {

    public void performAction() {
        // Code that can alter isActionable state since it is not constant
        isActionable = true;
    }
}

Si ces classes sont chargées dans une seule machine virtuelle Java par un chargeur de NuclearActionclasse, le comportement de peut être affecté par une autre classe, CleanActionlorsqu'elle performAction()est invoquée après CleanActionl'exécution de (dans le même thread ou autrement), ce qui dans ce cas peut être désastreux (c'est sémantique).

Puisque nous ne savons pas comment chaque implémentation d'un interfaceva utiliser ces variables, elles doivent implicitement l'être final.


9

Parce que tout le reste fait partie de l'implémentation et que les interfaces ne peuvent contenir aucune implémentation.


1
alors quelle est la raison de la finale.
Jothi

7
Pour indiquer que c'est une constante. Java n'a pas de mot clé const. statique finale est la façon dont vous déclarez les constantes.
Amir Afghani

5
Depuis Java 8, ils peuvent contenir une implémentation, mais il est fortement recommandé de ne pas l'utiliser si vous n'avez pas besoin de compatibilité backwarts. :)
codepleb

6
public interface A{
    int x=65;
}
public interface B{
    int x=66;
}
public class D implements A,B {
    public static void main(String[] a){
        System.out.println(x); // which x?
    }
}

Voici la solution.

System.out.println(A.x); // done

Je pense que c'est la seule raison pour laquelle les variables d'interface sont statiques.

Ne déclarez pas de variables dans Interface.


3
En fait, sans la spécification "Axe", il ne serait même pas compilé ", donc il est en fait sûr d'utiliser des variables (qui sont implicitement publiques statiques finales) dans les interfaces.
Marco

Je ne suis pas d'accord avec la réponse, car @Marco a dit qu'elle ne compilerait même pas. Je n'ai pas trouvé d'autre inconvénient jusqu'à présent, peut-être juste que vous ne voyez pas écrit static finalavant la variable qui est en fait statique et finale.
Micer

5

statique - car l'interface ne peut avoir aucune instance. et finale - parce que nous n'avons pas besoin de la changer.


15
"nous n'avons pas besoin de" == "nous ne sommes pas autorisés", ne mélangez pas les significations.
peterh

3

car:

Static : comme nous ne pouvons pas avoir d'objets d'interfaces, nous devons donc éviter d'utiliser des variables membres de niveau objet et utiliser des variables de niveau classe, c'est-à-dire statiques.

Final : pour ne pas avoir de valeurs ambiguës pour les variables (problème Diamond - Héritage Multiple).

Et selon l'interface de documentation est un contrat et non une implémentation.

référence: la réponse d' Abhishek Jain sur quora


2

Java n'autorise pas les variables abstraites et / ou les définitions de constructeur dans les interfaces. Solution: Accrochez simplement une classe abstraite entre votre interface et votre implémentation qui étend uniquement la classe abstraite comme ceci:

 public interface IMyClass {

     void methodA();
     String methodB();
     Integer methodC();

 }

 public abstract class myAbstractClass implements IMyClass {
     protected String varA, varB;

     //Constructor
     myAbstractClass(String varA, String varB) {
         this.varA = varA;
         this.varB = VarB;
     }

     //Implement (some) interface methods here or leave them for the concrete class
     protected void methodA() {
         //Do something
     }

     //Add additional methods here which must be implemented in the concrete class
     protected abstract Long methodD();

     //Write some completely new methods which can be used by all subclasses
     protected Float methodE() {
         return 42.0;
     }

 }

 public class myConcreteClass extends myAbstractClass {

     //Constructor must now be implemented!
     myClass(String varA, String varB) {
         super(varA, varB);
     }

     //All non-private variables from the abstract class are available here
     //All methods not implemented in the abstract class must be implemented here

 }

Vous pouvez également utiliser une classe abstraite sans aucune interface si vous êtes SÛR de ne pas vouloir l'implémenter avec d'autres interfaces ultérieurement. Veuillez noter que vous ne pouvez pas créer une instance d'une classe abstraite, vous DEVEZ d'abord l'étendre.

(Le mot clé "protégé" signifie que seules les classes étendues peuvent accéder à ces méthodes et variables.)

spyro



1

Interface: service de configuration requise.

Dans l'interface, les variables sont assignées par défaut par un modificateur d'accès public, statique et final . Car :

public: Il arrive parfois que l'interface soit placée dans un autre package. Il doit donc accéder à la variable de n'importe où dans le projet.

statique: En tant que telle classe incomplète ne peut pas créer d'objet. Donc, dans le projet, nous devons accéder à la variable sans objet afin que nous puissions accéder à l'aide deinterface_filename.variable_name

final: Supposons qu'une interface implémente par plusieurs classes et que toutes les classes essaient d'accéder et de mettre à jour la variable d'interface. Cela conduit donc à des données incohérentes et changeantes et affecte toutes les autres classes. Il doit donc déclarer le modificateur d'accès avec final.


0

Dans Java, l'interface ne vous permet de déclarer aucune variable d'instance. L'utilisation d'une variable déclarée dans une interface comme variable d'instance retournera une erreur de temps de compilation.

Vous pouvez déclarer une variable constante, en utilisant static finalce qui est différent d'une variable d'instance.


C'est tout à fait faux. Le compilateur ne va pas se plaindre à moins que vous ne le rendiez privé ou protégé. Sous le capot, comme d'autres l'ont déjà mentionné, ils sont convertis en finale statique publique. Et je suppose que c'est assez évident pourquoi. Parce que l'interface est destinée à dicter le comportement, pas l'état.
Mikayil Abdullayev

0

L'interface peut être implémentée par n'importe quelle classe et si cette valeur est modifiée par l'une des classes implémentantes, il y aura des erreurs pour les autres classes implémentées. L'interface est fondamentalement une référence pour combiner deux entités corélatées mais différentes. Par conséquent, la variable déclarante à l'intérieur de l'interface sera implicitement finale et également statique car l'interface ne peut pas être instanciée.


0

Pensez à une application Web dans laquelle vous avez défini une interface et d'autres classes l'implémentent. Comme vous ne pouvez pas créer une instance d'interface pour accéder aux variables, vous devez avoir un mot-clé statique. Depuis sa statique, tout changement de valeur se reflétera sur les autres instances qui l'ont implémenté. Donc, pour l'empêcher, nous les définissons comme définitifs.


0

Juste essayé dans Eclipse, la variable dans l'interface est par défaut finale, donc vous ne pouvez pas la changer. Par rapport à la classe parente, les variables sont définitivement modifiables. Pourquoi? De mon point de vue, variable en classe est un attribut qui sera hérité par les enfants, et les enfants peuvent le changer en fonction de leurs besoins réels. Au contraire, l'interface ne définit que le comportement, pas l'attribut. La seule raison de mettre des variables dans l'interface est de les utiliser comme constantes liées à cette interface. Cependant, ce n'est pas une bonne pratique selon l'extrait suivant:

"Placer des constantes dans une interface était une technique populaire dans les premiers jours de Java, mais maintenant beaucoup la considèrent comme une utilisation désagréable des interfaces, car les interfaces devraient traiter les services fournis par un objet, pas ses données. De plus, les constantes utilisées par une classe sont généralement un détail d'implémentation, mais les placer dans une interface les promeut dans l'API publique de la classe. "

J'ai également essayé de mettre statique ou non, cela ne fait aucune différence. Le code est le suivant:

public interface Addable {
    static int count = 6;

    public int add(int i);

}

public class Impl implements Addable {

    @Override
    public int add(int i) {
        return i+count;
    }
}

public class Test {

    public static void main(String... args) {
        Impl impl = new Impl();

        System.out.println(impl.add(4));
    }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.