¿Por qué las variables de interfaz son estáticas y finales por defecto?

¿Por qué las variables de interfaz son estáticas y finales por defecto en Java?

De las preguntas frecuentes del diseño de la interfaz de Java por Philip Shaw:

Las variables de interfaz son estáticas porque las interfaces de Java no se pueden instanciar por sí mismas; el valor de la variable debe asignarse en un contexto estático en el que no existe instancia. El modificador final asegura que el valor asignado a la variable de interfaz es una constante verdadera que no puede ser reasignada por el código del progtwig.

fuente

Como la interfaz no tiene un objeto directo, la única forma de acceder a ellos es mediante el uso de una clase / interfaz y, por lo tanto, si existe una variable de interfaz, debe ser estática, de lo contrario no podrá accederse al mundo exterior. Ahora que es estático, puede contener solo un valor y cualquier clase que lo implemente puede cambiarlo y, por lo tanto, será un desastre.

Por lo tanto, si hay una variable de interfaz, será implícitamente estática, final y obviamente pública.

público : para la accesibilidad en todas las clases, al igual que los métodos presentes en la interfaz

static : como la interfaz no puede tener un objeto, el interfaceName.variableName se puede usar para hacer referencia a él o directamente a la variableName en la clase que lo implementa.

final : hacerlos constantes. Si 2 clases implementan la misma interfaz y les da a ambas el derecho de cambiar el valor, se producirá un conflicto en el valor actual de la var, por lo que solo se permite la inicialización de una vez.

Además, todos estos modificadores están implícitos para una interfaz, realmente no necesita especificar ninguno de ellos.

Porque cualquier otra cosa es parte de la implementación, y las interfaces no pueden contener ninguna implementación.

( Esta no es una respuesta filosófica sino más práctica ). El requisito para static modificador static es obvio y ha sido respondido por otros. Básicamente, dado que las interfaces no se pueden instanciar, la única forma de acceder a sus campos es convertirlas en un campo de clase: static .

La razón detrás de los campos de interface que se vuelven automáticamente final (constantes) es evitar que diferentes implementaciones cambien accidentalmente el valor de la variable de interfaz que puede afectar inadvertidamente el comportamiento de las otras implementaciones. Imagine el siguiente escenario donde una propiedad de interface no se convirtió explícitamente en final por 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!!! } } } 

Ahora, solo piense qué pasaría si otra clase que implementa Actionable altera el estado de la variable de interfaz:

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

Si estas clases son cargadas dentro de una sola JVM por un cargador de clases, entonces el comportamiento de NuclearAction puede verse afectado por otra clase, CleanAction , cuando se invoque a performAction() después de que se CleanAction (en el mismo hilo o de otro modo), que en este caso puede ser desastroso (semánticamente eso es).

Como no sabemos cómo cada implementación de una interface va a usar estas variables, deben ser implícitamente final .

estático – porque la interfaz no puede tener ninguna instancia. y final, porque no necesitamos cambiarlo.

 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? } } 

Aquí está la solución.

 System.out.println(Ax); // done 

Creo que es la única razón por la cual la variable de interfaz es estática.

No declare variables dentro de la interfaz.

Java no permite las variables abstractas y / o las definiciones de los constructores en las interfaces. Solución: simplemente cuelgue una clase abstracta entre su interfaz y su implementación, que solo amplía la clase abstracta de la siguiente manera:

  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 } 

También puede usar una clase abstracta sin ninguna interfaz si está SEGURO de que no desea implementarla junto con otras interfaces más adelante. Tenga en cuenta que no puede crear una instancia de una clase abstracta. DEBE extenderla primero.

(La palabra clave “protegida” significa que solo las clases ampliadas pueden acceder a estos métodos y variables).

spyro

Una interfaz es un contrato entre dos partes que es invariable, tallado en la piedra, por lo tanto final. Ver diseño por contrato .

porque:

Static : como no podemos tener objetos de interfaces, deberíamos evitar el uso de variables miembro de nivel de objeto y deberíamos usar variables de nivel de clase, es decir, estáticas.

Final : para que no tengamos valores ambiguos para las variables (Problema de diamante – Herencia múltiple).

Y según la interfaz de documentación, es un contrato y no una implementación.

referencia: respuesta de Abhishek Jain en la quora http://qr.ae/TU1dTm

En Java , la interfaz no le permite declarar ninguna variable de instancia. Usar una variable declarada en una interfaz como una variable de instancia devolverá un error de tiempo de comstackción.

Puede declarar una variable constante, usando static final que es diferente de una variable de instancia.

La interfaz puede ser implementada por cualquier clase y qué pasa si ese valor fue cambiado por uno de los que implementan la clase, entonces habrá error para otras clases de implementación. La interfaz es básicamente una referencia para combinar dos entidades correlacionadas pero diferentes. Por esta razón, la variable de statement dentro de la interfaz será implícitamente definitiva y también estática porque la interfaz no puede crear instancias.

Piense en una aplicación web en la que tenga una interfaz definida y otras clases que la implementen. Como no puede crear una instancia de interfaz para acceder a las variables, necesita tener una palabra clave estática. Como está estática, cualquier cambio en el valor se reflejará en otras instancias que lo hayan implementado. Entonces, para evitarlo, los definimos como definitivos.

Acabo de probar en Eclipse, la variable en la interfaz es predeterminada para ser definitiva, por lo que no puede cambiarla. En comparación con la clase de padres, las variables son definitivamente modificables. ¿Por qué? Desde mi punto, la variable en clase es un atributo que heredarán los niños, y los niños pueden cambiarlo de acuerdo con sus necesidades reales. Por el contrario, la interfaz solo define el comportamiento, no el atributo. La única razón para incluir variables en la interfaz es usarlas como constelaciones relacionadas con esa interfaz. Sin embargo, esta no es una buena práctica según el siguiente extracto:

“Colocar constantes en una interfaz era una técnica popular en los primeros días de Java, pero ahora muchos lo consideran un uso desagradable de las interfaces, ya que las interfaces deben tratar los servicios proporcionados por un objeto, no sus datos. por una clase son típicamente un detalle de implementación, pero colocarlos en una interfaz los promueve a la API pública de la clase “.

También intenté o bien poner estático o no hace ninguna diferencia en absoluto. El código es el siguiente:

 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)); } }