Pourquoi les variables d'interface sont-elles statiques et finales par défaut en Java?
Pourquoi les variables d'interface sont-elles statiques et finales par défaut en Java?
Réponses:
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.
static
modificateur 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 interface
ne puisse pas être instancié directement - vous pouvez toujours avoir des instances de classes qui implémentent le interface
et 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 final
signifie.
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 !!!
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.
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.
( Ce n'est pas une réponse philosophique mais plutôt une réponse pratique ). L'exigence d'un static
modificateur 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 interface
champs 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 interface
propriété n'est pas devenue explicitement final
par 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 Actionable
modifie 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 NuclearAction
classe, le comportement de peut être affecté par une autre classe, CleanAction
lorsqu'elle performAction()
est invoquée après CleanAction
l'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 interface
va utiliser ces variables, elles doivent implicitement l'être final
.
Parce que tout le reste fait partie de l'implémentation et que les interfaces ne peuvent contenir aucune implémentation.
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.
static final
avant la variable qui est en fait statique et finale.
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
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
Une Interface est un contrat entre deux parties qui est invariant, taillé dans la pierre, donc définitif. Voir Conception par contrat .
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.
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 final
ce 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 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.
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.
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));
}
}