El tema dice más: ¿cuál es la razón del hecho de que los métodos estáticos no se pueden declarar en una interfaz?
public interface ITest {
public static String test();
}
El código anterior me da el siguiente error (en Eclipse, al menos): "Modificador ilegal para el método de interfaz ITest.test (); solo se permiten public & abstract".
Respuestas:
Hay algunos problemas en juego aquí. El primero es la cuestión de declarar un método estático sin definirlo. Esta es la diferencia entre
y
La primera es imposible por las razones que menciona Espo : no sabes qué clase de implementación es la definición correcta.
Java podría permitir esto último; y de hecho, comenzando en Java 8, ¡lo hace!
fuente
static
métodos en uninterface
. Los métodos deben serpublic
.La razón por la que no puede tener un método estático en una interfaz radica en la forma en que Java resuelve las referencias estáticas. Java no se molestará en buscar una instancia de una clase cuando intente ejecutar un método estático. Esto se debe a que los métodos estáticos no dependen de la instancia y, por lo tanto, se pueden ejecutar directamente desde el archivo de clase. Dado que todos los métodos en una interfaz son abstractos, la VM tendría que buscar una implementación particular de la interfaz para encontrar el código detrás del método estático para poder ejecutarlo. Esto contradice cómo funciona la resolución del método estático e introduciría una inconsistencia en el lenguaje.
fuente
Contestaré tu pregunta con un ejemplo. Supongamos que tenemos una clase de matemáticas con un método estático agregar. Llamarías a este método así:
Si Math fuera una interfaz en lugar de una clase, no podría tener ninguna función definida. Como tal, decir algo como Math.add (2, 3) no tiene sentido.
fuente
La razón radica en el principio de diseño, que Java no permite la herencia múltiple. El problema con la herencia múltiple se puede ilustrar con el siguiente ejemplo:
¿Qué sucede si llamas a Cx ()? ¿Se ejecutará Ax () o Bx ()? Cada idioma con herencia múltiple tiene que resolver este problema.
Las interfaces permiten en Java algún tipo de herencia múltiple restringida. Para evitar el problema anterior, no se les permite tener métodos. Si observamos el mismo problema con las interfaces y los métodos estáticos:
El mismo problema aquí, ¿qué sucede si llamas a Cx ()?
fuente
A
contenerint x(int z);
y la interfazB
contenerstring x(int x);
? ¿Cuál es el significado dex(3)
en la interfaz C?Los métodos estáticos no son métodos de instancia. No hay contexto de instancia, por lo tanto, implementarlo desde la interfaz tiene poco sentido.
fuente
Ahora Java8 nos permite definir incluso métodos estáticos en la interfaz.
Nota: Los métodos en la interfaz siguen siendo abstractos públicos de forma predeterminada si no utilizamos explícitamente las palabras clave default / static para convertirlos en métodos predeterminados y métodos estáticos resp.
fuente
Hay una respuesta muy agradable y concisa a su pregunta aquí . (Me pareció una forma tan directa de explicarlo que quiero vincularlo desde aquí).
fuente
Parece que el método estático en la interfaz podría ser compatible con Java 8 , bueno, mi solución es simplemente definirlos en la clase interna.
La misma técnica también se puede utilizar en anotaciones:
Siempre se debe acceder a la clase interna en forma de, en
Interface.fn...
lugar deClass.fn...
, entonces, puede deshacerse del problema ambiguo.fuente
Se utiliza una interfaz para el polimorfismo, que se aplica a objetos, no a tipos. Por lo tanto (como ya se señaló) no tiene sentido tener un miembro de interfaz estático.
fuente
Java 8 había cambiado el mundo, puedes tener métodos estáticos en la interfaz, pero te obliga a proporcionar una implementación para eso.
}
fuente
Combinación ilegal de modificadores: estática y abstracta.
Si un miembro de una clase se declara como estático, se puede usar con su nombre de clase que se limita a esa clase, sin crear un objeto.
Si un miembro de una clase se declara como abstracto, debe declarar la clase como abstracta y debe proporcionar la implementación del miembro abstracto en su clase heredada (Subclase).
Debe proporcionar una implementación al miembro abstracto de una clase en la subclase donde va a cambiar el comportamiento del método estático, también declarado como abstracto, que está confinado a la clase base, lo cual no es correcto.
fuente
Dado que los métodos estáticos no se pueden heredar. Así que no sirve de nada colocarlo en la interfaz. La interfaz es básicamente un contrato que todos sus suscriptores deben seguir. Colocar un método estático en la interfaz obligará a los suscriptores a implementarlo. que ahora se vuelve contradictorio al hecho de que los métodos estáticos no se pueden heredar.
fuente
Por ejemplo, Comparator tiene un método estático naturalOrder ().
El requisito de que las interfaces no pueden tener implementaciones también se ha relajado. Las interfaces ahora pueden declarar implementaciones de métodos "predeterminados", que son como implementaciones normales con una excepción: si hereda tanto una implementación predeterminada de una interfaz como una implementación normal de una superclase, la implementación de la superclase siempre tendrá prioridad.
fuente
Quizás un ejemplo de código ayudaría, voy a usar C #, pero debería poder seguirlo.
Supongamos que tenemos una interfaz llamada IPayable
Ahora, tenemos dos clases concretas que implementan esta interfaz:
Ahora, supongamos que tenemos una colección de varias cuentas, para ello utilizaremos una lista genérica del tipo IPayable
Ahora, queremos pagar $ 50.00 a todas esas cuentas:
Así que ahora ves cómo las interfaces son increíblemente útiles.
Se usan solo en objetos instanciados. No en clases estáticas.
Si hubiera hecho que el pago fuera estático, al recorrer los IPayable en accountsToPay no habría forma de averiguar si debería llamar a pagar en BusinessAcount o CustomerAccount.
fuente