Definir un método estático en la interfaz de Java
-
Método
estático
en lainterfaz
de Java -
Importancia de Usar Métodos
estáticos
en unainterfaz
-
Reglas para métodos
estáticos
en unainterfaz
-
Razones para no tener métodos
estáticos
en interfaces anteriores a Java 8 -
Razones para no poder anular un método
estático
Este tutorial enumera las reglas para tener métodos estáticos
en la interfaz
de Java y demuestra cómo definirlos y por qué no podemos anularlos. También exploraremos las razones para no tener métodos estáticos
en las interfaces antes de Java 8.
Método estático
en la interfaz
de Java
Antes de entrar en los métodos estáticos
en las interfaces de Java, es importante saber acerca de una interfaz
, que contiene uno o varios métodos abstractos
(los métodos sin cuerpo) definidos en la clase que implementa
esta interfaz
.
Tenga en cuenta que estos métodos abstractos
son métodos públicos
, ya sea que escribamos el modificador público
o no.
Código de ejemplo:
public interface Messages {
// public & abstract
public void display();
}
public class Test implements Messages {
// implementation of abstract method
public void display() {
System.out.println("Hi! Welcome to the DelftStack");
}
public static void main(String[] args) {
Test test = new Test();
test.display();
}
}
Producción :
Hi! Welcome to the DelftStack
Recuerde, el método abstracto
llamado display()
es un método público
, tenemos que instanciar la clase Test
para ejecutar el método display()
.
Por otro lado, el método estático
está asociado a la propia clase en la que se definen, y no necesitamos instanciar la clase para utilizar estos métodos estáticos
. A partir de Java 8, ahora podemos tener métodos de interfaz estáticos
.
Ahora, tenemos un cuerpo completo y todas las instrucciones necesarias para ese método estático
específico en la interfaz
. Recuerda que a los métodos estáticos
solo se puede acceder a nivel de clase, no a nivel de instancia.
Entonces, podemos acceder a los métodos estáticos
de la siguiente manera.
Código de ejemplo:
public interface Messages {
// static method
static void display() {
System.out.println("Hello! Nice to meet you");
}
}
public class Test {
public static void main(String[] args) {
Messages.display();
}
}
Producción :
Hello! Nice to meet you
La pregunta es ¿podemos anular un método estático
? No, no podemos anular un método estático
. De lo contrario, obtendremos un error de compilación.
Además, no podemos llamarlos a través de una instancia de una clase implementadora ya que los métodos estáticos
están ocultos. Vea el siguiente ejemplo que produce un error de compilación.
Código de ejemplo:
public interface Messages {
static void display() {
System.out.println("Hello! Nice to meet you");
}
}
public class Test implements Messages {
@Override
public void display() {
System.out.println("Override");
}
public static void main(String[] args) {
Test test = new Test();
test.display();
}
}
A continuación se muestra la descripción del error producido por la valla de código anterior.
Producción :
Test.java:25: error: method does not override or implement a method from a supertype
@Override
^
1 error
Importancia de Usar Métodos estáticos
en una interfaz
Podemos obtener los siguientes beneficios del uso de métodos estáticos
en las interfaces de Java.
- Un método
estático
de unainterfaz
encapsula el comportamiento que no queremos que las subclases o subinterfaces hereden o anulen. - Estos métodos
estáticos
de unainterfaz
de Java son útiles para desarrollar utilidades reutilizables que no están restringidas a tipos de clases de implementación particulares.
Reglas para métodos estáticos
en una interfaz
La siguiente sección muestra las reglas para las ventajas anteriores en el uso de métodos estáticos
.
Los métodos predeterminados de una interfaz contienen la instrucción para el comportamiento predeterminado, y la clase de implementación puede optar por proporcionar instrucciones más concretas anulándolas o heredándolas tal como están. Al igual que los métodos predeterminados, los métodos estáticos
contienen un cuerpo (conjunto de instrucciones) para su comportamiento, pero no se permite que una clase de implementación herede o anule un método estático
de su interfaz
, como hemos aprendido anteriormente.
Alguien con un método estático
en una interfaz
de Java debe recordar las siguientes reglas.
- Estos métodos deben tener un cuerpo.
- Solo podemos ejecutar estos métodos
estáticos
usando un nombre deinterfaz
. - Estos métodos deben tener un modificador
estático
en la declaración del método. Si no especifica, seríapúblico
por defecto. Recuerda, también podemos hacerlosprivados
si queremos. - No pueden invocar otros métodos
abstractos
o por defecto. - No se permite que las subclases o subinterfaces anulen o hereden estos métodos
estáticos
.
Ahora, en este punto, es posible que tenga dos preguntas en mente.
- ¿Por qué no podíamos tener métodos
estáticos
en los viejos tiempos (antes del lanzamiento de Java 8)? - ¿Por qué no podemos anular los métodos
estáticos
?
Averigüemos las respuestas a ambas preguntas.
Razones para no tener métodos estáticos
en interfaces anteriores a Java 8
No había una causa técnica sólida y principal por la que las interfaces de Java no tuvieran métodos “estáticos” antes del lanzamiento de Java 8. Estos métodos “estáticos” se consideraron pequeñas actualizaciones o cambios del lenguaje, y luego hubo una propuesta oficial para agregarlo en Java. 7, pero luego se abandonó debido a algunas complicaciones.
Finalmente, en Java 8, nos presentaron los métodos estáticos
en las interfaces. A partir de Java 8, también aprendimos sobre funciones/métodos de instancia anulables con implementaciones predeterminadas.
Recuerde, todavía no contenían campos de instancia. Estas características son parte del soporte de expresión lambda
que puede leer aquí (JSR 335 Parte H).
Razones para no poder anular un método estático
Los métodos estáticos
se resuelven en tiempo de compilación. Los envíos dinámicos tienen sentido en los métodos de instancia en los que un compilador no puede determinar el tipo concreto del objeto; por lo tanto, no podemos resolver un método para invocar.
Pero necesitamos una clase para ejecutar un método estático
; dado que esa clase específica se conoce estáticamente
—en tiempo de compilación— no es necesario un envío dinámico.
Supongamos que cada clase tiene un HashTable
que asigna la firma de un método (nombre y tipos de parámetros) a la pieza de código real para implementar el método. Cuando la VM intenta ejecutar un método en una instancia, consulta un objeto por su clase y busca la firma solicitada en una tabla de clases.
Se invoca si se encuentra el cuerpo del método; de lo contrario, se obtiene la clase principal de la clase donde se repite la búsqueda. Este proceso continúa hasta que se encuentra un método o no quedan más clases principales (lo que produce NoSuchMethodError
).
Si las tablas respectivas tienen una entrada para una subclase y una superclase para la misma firma de método, la versión de la subclase se encontraría primero y la versión de la superclase nunca se usaría; esto es una anulación
.
Suponiendo que omitamos una instancia de objeto y comencemos con la subclase, la resolución podría proceder como se indicó anteriormente, brindándole una especie de método estático
anulable
. Tenga en cuenta que esta resolución solo puede ocurrir en tiempo de compilación.
Sin embargo, sabemos que un compilador comienza desde la clase conocida en lugar de esperar hasta el tiempo de ejecución para consultar el objeto de un tipo no especificado para su clase. Por lo tanto, no tendría sentido anular un método estático
.