¿Por qué las variables de interfaz son estáticas y finales por defecto en Java?
¿Por qué las variables de interfaz son estáticas y finales por defecto en Java?
Respuestas:
Desde el diseño de la interfaz Java Preguntas frecuentes por Philip Shaw:
Las variables de interfaz son estáticas porque las interfaces de Java no se pueden instanciar por derecho propio; El valor de la variable debe asignarse en un contexto estático en el que no exista ninguna instancia. El modificador final asegura que el valor asignado a la variable de interfaz es una constante real que no puede ser reasignada por el código del programa.
static
modificador es completamente espuria. Las variables de instancia pública de una clase son parte de su interfaz y no hay razón para que no se abstraigan en Java interface
, al igual que los métodos de instancia. No importa que un Java interface
no pueda ser instanciado directamente; aún puede tener instancias de clases que implementen interface
y es sensato exigir que tengan una determinada variable de instancia pública. En cuanto a la parte sobre final
, eso no ofrece una explicación en absoluto, solo describe lo que final
significa.
Dado que 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, debería ser estática; de lo contrario, no será accesible para el mundo exterior. Ahora, dado que es estático, solo puede contener un valor y cualquier clase que lo implemente puede cambiarlo y, por lo tanto, será todo un desastre.
Por lo tanto, si existe una variable de interfaz, será implícitamente estática, final y obviamente pública.
interface
. Una clase implementaría la interfaz, declarando la variable de instancia (como lo requiere la interfaz). Su constructor (u otro método) establece la variable de instancia. Cuando se instancia una instancia de la clase, podrá acceder a su variable de instancia.
public : 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, se puede usar interfaceName.variableName para hacer referencia a él o directamente el variableName en la clase que lo implementa.
final : hacerlos constantes. Si 2 clases implementan la misma interfaz y les da a ambos 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.
( Esta no es una respuesta filosófica, sino más práctica ). El requisito del static
modificador 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 convertirlos en un campo de clase static
.
La razón por la que los interface
campos se vuelven automáticamente final
(constantes) es para 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 en el que una interface
propiedad no se convirtió explícitamente en final
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, piense qué sucederí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 un cargador de clases carga estas clases dentro de una sola JVM, entonces el comportamiento de NuclearAction
puede verse afectado por otra clase CleanAction
, cuando performAction()
se invoca después CleanAction
de que se ejecuta (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 un interface
va a utilizar estas variables, deben serlo implícitamente final
.
Porque cualquier otra cosa es parte de la implementación, y las interfaces no pueden contener ninguna implementación.
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(A.x); // done
Creo que es la razón por la cual las variables de interfaz son estáticas.
No declare variables dentro de la interfaz.
static final
antes de la variable que en realidad es estática y final.
estática, porque la interfaz no puede tener ninguna instancia. y final, porque no necesitamos cambiarlo.
porque:
Static
: como no podemos tener objetos de interfaces, debemos evitar el uso de variables miembro de nivel de objeto y debemos usar variables de nivel de clase, es decir, estático.
Final
: para que no debamos tener 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: la respuesta de Abhishek Jain sobre quora
Java no permite variables abstractas y / o definiciones de constructor en las interfaces. Solución: simplemente cuelgue una clase abstracta entre su interfaz y su implementación que solo extiende 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 extendidas pueden acceder a estos métodos y variables).
spyro
Una interfaz es un contrato entre dos partes que es invariante, tallado en la piedra y, por lo tanto, definitivo. Ver Diseño por contrato .
Interfaz: Servicio de requisitos del sistema.
En la interfaz, las variables se asignan de manera predeterminada mediante un modificador de acceso final público, estático . Porque :
public: A veces sucede que la interfaz puede colocarse en otro paquete. Por lo tanto, debe acceder a la variable desde cualquier parte del proyecto.
estática: Como tal, la clase incompleta no puede crear objetos. Entonces, en el proyecto necesitamos acceder a la variable sin objeto para poder acceder con la ayuda deinterface_filename.variable_name
final: supongamos que una clase se implementa por muchas clases y todas las clases intentan acceder y actualizar la variable de la interfaz. Por lo tanto, genera inconsistencia en el cambio de datos y afecta a todas las demás clases. Por lo tanto, debe declarar el modificador de acceso con final.
En Java
, la interfaz no le permite declarar ninguna variable de instancia. El uso de una variable declarada en una interfaz como variable de instancia devolverá un error de tiempo de compilación.
Puede declarar una variable constante, utilizando static final
cuál es diferente de una variable de instancia.
La interfaz puede ser implementada por cualquier clase y si ese valor se modifica por una de las clases implementadoras, habrá engaño para otras clases implementadoras. La interfaz es básicamente una referencia para combinar dos entidades coreladas pero diferentes. Por lo tanto, la variable de declaración dentro de la interfaz será implícitamente final y también estática porque la interfaz no puede ser instanciada.
Piense en una aplicación web donde tiene una interfaz definida y otras clases la implementan. Como no puede crear una instancia de interfaz para acceder a las variables, debe tener una palabra clave estática. Dado que es estático, cualquier cambio en el valor se reflejará en otras instancias que lo hayan implementado. Entonces, para evitarlo, los definimos como finales.
Acabo de probar en Eclipse, la variable en la interfaz es predeterminada para ser final, por lo que no puede cambiarla. En comparación con la clase padre, las variables son definitivamente cambiables. ¿Por qué? Desde mi punto de vista, la variable en clase es un atributo que será heredado por los niños, y los niños pueden cambiarlo según su necesidad real. Por el contrario, la interfaz solo define el comportamiento, no el atributo. La única razón para poner variables en la interfaz es usarlas como consts 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 con los servicios proporcionados por un objeto, no sus datos. Además, las constantes utilizadas por 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é poner estática o no hacer ninguna diferencia. 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));
}
}