Pourquoi les variables d'interface sont-elles statiques et finales par défaut en Java?
Depuis la Java conception de l'interface FAQ de Philip Shaw:
Les variables d'interface sont statiques car les interfaces Java ne peuvent pas être instanciées par elles-mêmes; 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 constante vraie qui ne peut pas être réaffectée par le code du programme.
Puisque l'interface n'a pas d'objet direct, le seul moyen d'y accéder consiste à utiliser une classe/interface. C'est pourquoi, si une variable d'interface existe, elle doit être statique, sinon elle ne sera pas accessible du tout au monde extérieur. Maintenant, comme il est statique, il ne peut contenir qu'une seule valeur et toutes les classes qui l'implémentent peuvent la changer et par conséquent, tout sera en désordre.
Donc s'il y a une variable d'interface, elle sera implicitement statique, finale et évidemment publique !!!
public: pour l'accessibilité à travers toutes les classes, tout comme les méthodes présentes dans l'interface
statique: l'interface ne pouvant pas avoir d'objet, le nom d'interface.nomvariable peut être utilisé pour le référencer ou directement le nom de variable dans la classe l'implémentant.
final: pour les rendre constantes. Si 2 classes implémentent la même interface et que vous leur accordez le droit de modifier la valeur, la valeur actuelle de la variable variera en conflit, raison pour laquelle une seule initialisation est autorisée.
De plus, tous ces modificateurs sont implicites pour une interface, vous n'avez pas vraiment besoin de les spécifier.
(Ceci n'est pas une réponse philosophique mais plus pratique). La nécessité de modifier static
est évidente et a déjà été remplie. Fondamentalement, étant donné que les interfaces ne peuvent pas être instanciées, le seul moyen d'accéder à ses champs consiste à les transformer en champ de classe - static
.
La raison derrière les champs interface
devenant automatiquement final
(constante) 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 propriété interface
ne soit pas explicitement devenue final
de 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, imaginez ce qui se produirait si une autre classe implémentant Actionable
modifiait 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 un classloader charge ces classes dans une seule machine virtuelle Java, le comportement de NuclearAction
peut être affecté par une autre classe, CleanAction
, lorsque sa performAction()
est invoquée après CleanAction
. est exécuté (dans le même thread ou autrement), ce qui dans ce cas peut être désastreux (c'est-à-dire sémantiquement).
Puisque nous ne savons pas comment chaque implémentation d'une interface
va utiliser ces variables, elles doivent implicitement être final
.
Parce que tout le reste fait partie de la mise en œuvre et que les interfaces ne peuvent contenir aucune mise en œuvre.
static - car l'interface ne peut avoir aucune instance. et final - parce que nous n'avons pas besoin de le changer.
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 pas déclarer les variables dans l'interface.
parce que:
Static
: comme nous ne pouvons pas avoir d’objets d’interfaces, nous devons éviter d’utiliser des variables membres au niveau de l’objet et utiliser des variables au niveau classe, c’est-à-dire statiques.
Final
: afin de ne pas avoir de valeurs ambiguës pour les variables (problème de Diamond - Multiple Hheritance).
Et selon l'interface de documentation, c'est un contrat et non une implémentation.
reference: Abhishek Jain's réponse sur quora
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 de la manière suivante:
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 n'importe quelle interface si vous êtes SÛR que vous ne voulez pas 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é "protected" signifie que seules les classes étendues peuvent accéder à ces méthodes et variables.)
spyro
Une interface est un contrat invariant entre deux parties, gravé dans la pierre, donc définitif. Voir Conception par contrat .
Pensez à une application Web où vous avez défini une interface et que 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 valeur statique, toute modification de la valeur sera répercutée sur les autres instances qui l’ont implémentée. Donc, pour éviter cela, nous les définissons comme final.
Venu d’essayer dans Eclipse, la variable d’interface est par défaut finale, vous ne pouvez donc 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. Bien que ce ne soit pas une bonne pratique selon l'extrait suivant:
"Au début de Java, l'implantation de constantes dans une interface était une technique répandue, mais beaucoup considèrent aujourd'hui qu'il s'agit d'une utilisation désagréable des interfaces, car les interfaces doivent traiter les services fournis par un objet, et non 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 valorise vers l'API publique de la classe. "
J'ai aussi essayé soit de mettre statique ou non ne fait aucune différence. Le code est comme ci-dessous:
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));
}
}
Dans Java
, l'interface ne vous permet pas de déclarer des variables d'instance. L'utilisation d'une variable déclarée dans une interface en tant que variable d'instance renverra une erreur lors de la compilation.
Vous pouvez déclarer une variable constante en utilisant static final
qui est différent d'une variable d'instance.
L’interface peut être implémentée par n’importe quelle classe et si cette valeur était modifiée par l’une de ses classes d’implémentation, il y aurait confusion pour les autres classes implémentées. L'interface est fondamentalement une référence pour combiner deux entités corrélées mais différentes. Pour cette raison, la variable déclarante à l'intérieur de l'interface sera implicitement finale et statique car l'interface ne peut pas être instanciée.