method - ¿Por qué no puedo definir un método estático en una interfaz Java?
static interface c# (24)
¿Por qué no puedo definir un método estático en una interfaz Java?
En realidad se puede en Java 8.
Según el docs.oracle/staticMethod Java:
Un método estático es un método que está asociado con la clase en la que se define en lugar de con cualquier objeto. Cada instancia de la clase comparte sus métodos estáticos.
En Java 8, una interfaz puede tener métodos predeterminados y métodos estáticos . Esto nos facilita la organización de métodos de ayuda en nuestras bibliotecas. Podemos mantener métodos estáticos específicos para una interfaz en la misma interfaz en lugar de en una clase separada.
Ejemplo de método por defecto:
list.sort(ordering);
en lugar de
Collections.sort(list, ordering);
Ejemplo de método estático (desde el propio docs.oracle/staticMethod ):
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
Aquí está el ejemplo:
public interface IXMLizable<T>
{
static T newInstanceFromXML(Element e);
Element toXMLElement();
}
Por supuesto esto no funcionará. ¿Pero por qué no?
Uno de los posibles problemas sería, qué sucede cuando llama:
IXMLizable.newInstanceFromXML(e);
En este caso, creo que debería llamar a un método vacío (es decir, {}). Todas las subclases se verían obligadas a implementar el método estático, por lo que todas estarían bien al llamar al método estático. Entonces, ¿por qué esto no es posible?
EDITAR: Supongo que estoy buscando una respuesta que sea más profunda que "porque así es Java".
¿Hay alguna razón tecnológica particular por la que los métodos estáticos no puedan ser sobrescritos? Es decir, ¿por qué los diseñadores de Java decidieron hacer que los métodos de instancia sean anulables pero no métodos estáticos?
EDITAR: El problema con mi diseño es que estoy tratando de usar interfaces para hacer cumplir una convención de codificación.
Es decir, el objetivo de la interfaz es doble:
Quiero que la interfaz IXMLizable me permita convertir las clases que lo implementan en elementos XML (usando polimorfismo, funciona bien).
Si alguien quiere crear una nueva instancia de una clase que implementa la interfaz IXMLizable, siempre sabrá que habrá un constructor estático newInstanceFromXML (Element e).
¿Hay alguna otra manera de asegurar esto, aparte de poner un comentario en la interfaz?
EDITAR: A partir de Java 8, los métodos estáticos ahora están permitidos en las interfaces.
Java 8 permite métodos de interfaz estáticos
Con Java 8, las interfaces pueden tener métodos estáticos. También pueden tener métodos de instancia concretos, pero no campos de instancia.
Realmente hay dos preguntas aquí:
- ¿Por qué, en los viejos tiempos, las interfaces no podían contener métodos estáticos?
- ¿Por qué no se pueden anular los métodos estáticos?
Métodos estáticos en interfaces
No había una razón técnica sólida por la que las interfaces no pudieran tener métodos estáticos en versiones anteriores. Esto se resume muy bien en el póster de una pregunta duplicada. Los métodos de interfaz estática se consideraron inicialmente como un pequeño cambio de idioma, y luego hubo una propuesta oficial para agregarlos en Java 7, pero luego se eliminó debido a complicaciones imprevistas.
Finalmente, Java 8 introdujo métodos de interfaz estáticos, así como métodos de instancia con posibilidad de anulación con una implementación predeterminada. Aún así no pueden tener campos de instancia. Estas características son parte del soporte de la expresión lambda, y puede leer más sobre ellas en la Parte H de JSR 335.
Anulando métodos estáticos
La respuesta a la segunda pregunta es un poco más complicada.
Los métodos estáticos se pueden resolver en tiempo de compilación. El envío dinámico tiene sentido para los métodos de instancia, donde el compilador no puede determinar el tipo concreto del objeto y, por lo tanto, no puede resolver el método para invocar. Pero invocar un método estático requiere una clase, y como esa clase se conoce estáticamente , en tiempo de compilación, el envío dinámico no es necesario.
Es necesario un poco de historia sobre cómo funcionan los métodos de instancia para entender qué está pasando aquí. Estoy seguro de que la implementación real es bastante diferente, pero permítanme explicar mi noción de envío de métodos, que modela el comportamiento observado con precisión.
Haga de cuenta que cada clase tiene una tabla hash que mapea las firmas del método (nombre y tipos de parámetros) a una porción real de código para implementar el método. Cuando la máquina virtual intenta invocar un método en una instancia, consulta el objeto por su clase y busca la firma solicitada en la tabla de la clase. Si se encuentra un cuerpo de método, se invoca. De lo contrario, se obtiene la clase principal de la clase y la búsqueda se repite allí. Esto continúa hasta que se encuentra el método, o no hay más clases primarias, lo que resulta en un NoSuchMethodError
.
Si tanto una superclase como una subclase tienen una entrada en sus tablas para la misma firma de método, primero se encuentra la versión de la subclase y la versión de la superclase nunca se usa, esto es un "reemplazo".
Ahora, supongamos que omitimos la instancia del objeto y simplemente comenzamos con una subclase. La resolución podría proceder de la manera anterior, dándole una especie de método estático "sobrescribible". Sin embargo, toda la resolución puede suceder en tiempo de compilación, ya que el compilador está comenzando desde una clase conocida, en lugar de esperar hasta el tiempo de ejecución para consultar su objeto en un objeto de un tipo no especificado. No tiene sentido "anular" un método estático, ya que siempre se puede especificar la clase que contiene la versión deseada.
Constructor "interfaces"
Aquí hay un poco más de material para abordar la edición reciente de la pregunta.
Parece que desea IXMLizable
efectivamente un método similar a un constructor para cada implementación de IXMLizable
. Olvídese de tratar de hacer cumplir esto con una interfaz por un minuto y pretenda que tiene algunas clases que cumplen con este requisito. Cómo lo usarías?
class Foo implements IXMLizable<Foo> {
public static Foo newInstanceFromXML(Element e) { ... }
}
Foo obj = Foo.newInstanceFromXML(e);
Dado que tiene que nombrar explícitamente el tipo concreto Foo
cuando "construya" el nuevo objeto, el compilador puede verificar que sí tiene el método de fábrica necesario. Y si no es así, ¿y qué? Si puedo implementar un IXMLizable
que carece del "constructor", y creo una instancia y la paso a su código, es un IXMLizable
con toda la interfaz necesaria.
La construcción es parte de la implementación, no la interfaz. Cualquier código que funcione correctamente con la interfaz no se preocupa por el constructor. Cualquier código que se preocupa por el constructor debe conocer el tipo concreto de todos modos, y la interfaz puede ser ignorada.
Algo que podría implementarse es la interfaz estática (en lugar del método estático en una interfaz). Todas las clases que implementan una interfaz estática dada deben implementar los métodos estáticos correspondientes. Puede obtener una interfaz estática SI de cualquier clase usando
SI si = clazz.getStatic(SI.class); // null if clazz doesn''t implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null
entonces puedes llamar si.method(params)
. Esto sería útil (por ejemplo, para el patrón de diseño de fábrica) porque puede obtener (o verificar la implementación de) la implementación de métodos estáticos SI de una clase desconocida en tiempo de compilación. Es necesario un envío dinámico y puede anular los métodos estáticos (si no es el final) de una clase extendiéndolo (cuando se le llama a través de la interfaz estática). Obviamente, estos métodos solo pueden acceder a las variables estáticas de su clase.
Bueno, sin los genéricos, las interfaces estáticas son inútiles porque todas las llamadas a métodos estáticos se resuelven en tiempo de compilación. Por lo tanto, no hay un uso real para ellos.
Con los genéricos, tienen uso, con o sin una implementación predeterminada. Obviamente, tendría que haber anulación y así sucesivamente. Sin embargo, mi conjetura es que tal uso no fue muy OO (como las otras respuestas señalan de manera torpe) y, por lo tanto, no se consideró que valiera la pena el esfuerzo que requerirían para implementar de manera útil.
Comentario EDIT: As of Java 8, static methods are now allowed in interfaces.
Es correcto, los métodos estáticos desde Java 8 están permitidos en las interfaces, pero su ejemplo aún no funcionará. Simplemente no puede definir un método estático: debe implementarlo o obtendrá un error de compilación.
Con la llegada de Java 8 ahora es posible escribir métodos predeterminados y estáticos en la interfaz. docs.oracle/staticMethod
Por ejemplo:
public interface Arithmetic {
public int add(int a, int b);
public static int multiply(int a, int b) {
return a * b;
}
}
public class ArithmaticImplementation implements Arithmetic {
@Override
public int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int result = Arithmetic.multiply(2, 3);
System.out.println(result);
}
}
Resultado : 6
SUGERENCIA: La llamada a un método de interfaz estática no requiere que sea implementada por ninguna clase. Seguramente, esto sucede porque las mismas reglas para los métodos estáticos en las superclases se aplican a los métodos estáticos en las interfaces.
Debido a que los métodos estáticos no se pueden anular en las subclases, y por lo tanto no pueden ser abstractos. Y todos los métodos en una interfaz son, de hecho , abstractos.
Esto ya fue preguntado y contestado, here
Para duplicar mi respuesta:
Nunca hay un punto para declarar un método estático en una interfaz. No pueden ejecutarse mediante la llamada normal MyInterface.staticMethod (). Si los llama especificando la clase de implementación MyImplementor.staticMethod (), entonces debe conocer la clase real, por lo que es irrelevante si la interfaz la contiene o no.
Más importante aún, los métodos estáticos nunca se anulan, y si intenta hacer:
MyInterface var = new MyImplementingClass();
var.staticMethod();
las reglas de estática dicen que el método definido en el tipo declarado de var debe ejecutarse. Ya que esta es una interfaz, esto es imposible.
La razón por la que no puede ejecutar "result = MyInterface.staticMethod ()" es que tendría que ejecutar la versión del método definido en MyInterface. Pero no puede haber una versión definida en MyInterface, porque es una interfaz. No tiene código por definición.
Si bien puede decir que esto equivale a "porque Java lo hace de esa manera", en realidad la decisión es una consecuencia lógica de otras decisiones de diseño, también tomadas por muy buenas razones.
Las interfaces están relacionadas con el polimorfismo que está inherentemente vinculado a instancias de objetos, no a clases. Por lo tanto, la estática no tiene sentido en el contexto de una interfaz.
Las interfaces solo proporcionan una lista de cosas que proporcionará una clase, no una implementación real de esas cosas, que es lo que es su elemento estático.
Si desea estadísticas, utilice una clase abstracta y herede, de lo contrario, elimine la estática.
¡Espero que ayude!
Los métodos estáticos no son virtuales, como los métodos de instancia, así que supongo que los diseñadores de Java decidieron que no los querían en las interfaces.
Pero puedes poner clases que contengan métodos estáticos dentro de las interfaces. ¡Podrías intentar eso!
public interface Test {
static class Inner {
public static Object get() {
return 0;
}
}
}
No puede definir métodos estáticos en una interfaz porque los métodos estáticos pertenecen a una clase y no a una instancia de clase, y las interfaces no son clases. Leer más aquí.
Sin embargo, si quieres puedes hacer esto:
public class A {
public static void methodX() {
}
}
public class B extends A {
public static void methodX() {
}
}
En este caso, lo que tienes son dos clases con 2 métodos estáticos distintos llamados methodX ().
Normalmente esto se hace usando un patrón de fábrica
public interface IXMLizableFactory<T extends IXMLizable> {
public T newInstanceFromXML(Element e);
}
public interface IXMLizable {
public Element toXMLElement();
}
Para resolver esto: error: falta el cuerpo del método, o declare abstract static static vacío (String [] args);
interface I
{
int x=20;
void getValue();
static void main(String[] args){};//Put curly braces
}
class InterDemo implements I
{
public void getValue()
{
System.out.println(x);
}
public static void main(String[] args)
{
InterDemo i=new InterDemo();
i.getValue();
}
}
salida: 20
Ahora podemos usar el método estático en la interfaz.
Primero, todas las decisiones de lenguaje son decisiones tomadas por los creadores del lenguaje. No hay nada en el mundo de la ingeniería de software o la definición del lenguaje o la escritura del compilador / intérprete que diga que un método estático no puede ser parte de una interfaz. He creado un par de idiomas y compiladores escritos para ellos, es solo sentarme y definir semánticas significativas. Yo diría que la semántica de un método estático en una interfaz es muy clara, incluso si el compilador tiene que aplazar la resolución del método al tiempo de ejecución.
En segundo lugar, el uso de métodos estáticos significa que existe una razón válida para tener un patrón de interfaz que incluye métodos estáticos: no puedo hablar por ninguno de ustedes, pero uso métodos estáticos de forma regular.
La respuesta correcta más probable es que no hubo una necesidad percibida, en el momento en que se definió el lenguaje, para los métodos estáticos en las interfaces. Java ha crecido mucho a lo largo de los años y este es un elemento que aparentemente ha ganado cierto interés. El hecho de que se haya examinado para Java 7 indica que ha aumentado a un nivel de interés que podría resultar en un cambio de idioma. Yo, por mi parte, estaré contento cuando ya no tenga que instanciar un objeto solo para poder llamar a mi método getter no estático para acceder a una variable estática en una instancia de subclase ...
Si bien me doy cuenta de que Java 8 resuelve este problema, pensé que estaría de acuerdo con un escenario en el que actualmente estoy trabajando (bloqueado en el uso de Java 7) donde sería útil poder especificar métodos estáticos en una interfaz.
Tengo varias definiciones de enumeración donde he definido los campos "id" y "displayName" junto con los métodos de ayuda que evalúan los valores por varias razones. La implementación de una interfaz me permite asegurarme de que los métodos de obtención estén en su lugar pero no los métodos de ayuda estática. Al ser una enumeración, realmente no hay una forma clara de descargar los métodos auxiliares en una clase abstracta heredada o algo similar, por lo que los métodos deben definirse en la enumeración misma. Además, como es una enumeración, nunca podría pasarlo como un objeto instanciado y tratarlo como el tipo de interfaz, pero lo que me gusta es poder requerir la existencia de métodos auxiliares estáticos a través de una interfaz. siendo soportado en Java 8.
Aquí está el código que ilustra mi punto.
Definición de la interfaz:
public interface IGenericEnum <T extends Enum<T>> {
String getId();
String getDisplayName();
//If I was using Java 8 static helper methods would go here
}
Ejemplo de definición de una enumeración:
public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
STANDARD ("Standard", "Standard Mode"),
DEBUG ("Debug", "Debug Mode");
String id;
String displayName;
//Getter methods
public String getId() {
return id;
}
public String getDisplayName() {
return displayName;
}
//Constructor
private ExecutionModeType(String id, String displayName) {
this.id = id;
this.displayName = displayName;
}
//Helper methods - not enforced by Interface
public static boolean isValidId(String id) {
return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
}
public static String printIdOptions(String delimiter){
return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
}
public static String[] getIdArray(){
return GenericEnumUtility.getIdArray(ExecutionModeType.class);
}
public static ExecutionModeType getById(String id) throws NoSuchObjectException {
return GenericEnumUtility.getById(ExecutionModeType.class, id);
}
}
Definición de utilidad de enumeración genérica:
public class GenericEnumUtility {
public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(enumOption.getId().equals(id)) {
return true;
}
}
return false;
}
public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
String ret = "";
delimiter = delimiter == null ? " " : delimiter;
int i = 0;
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(i == 0) {
ret = enumOption.getId();
} else {
ret += delimiter + enumOption.getId();
}
i++;
}
return ret;
}
public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
List<String> idValues = new ArrayList<String>();
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
idValues.add(enumOption.getId());
}
return idValues.toArray(new String[idValues.size()]);
}
@SuppressWarnings("unchecked")
public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
id = id == null ? "" : id;
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(id.equals(enumOption.getId())) {
return (T)enumOption;
}
}
throw new NoSuchObjectException(String.format("ERROR: /"%s/" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
}
}
Supongamos que podrías hacerlo; Considera este ejemplo:
interface Iface {
public static void thisIsTheMethod();
}
class A implements Iface {
public static void thisIsTheMethod(){
system.out.print("I''m class A");
}
}
class B extends Class A {
public static void thisIsTheMethod(){
System.out.print("I''m class B");
}
}
SomeClass {
void doStuff(Iface face) {
IFace.thisIsTheMethod();
// now what would/could/should happen here.
}
}
Supongamos que se permiten métodos estáticos en las interfaces: * Forzarán a todas las clases implementadoras a declarar ese método. * Las interfaces normalmente se utilizarían a través de objetos, por lo que los únicos métodos efectivos en estos serían los no estáticos. * Cualquier clase que conozca una interfaz particular podría invocar sus métodos estáticos. Por lo tanto, un método estático de clase de implementación se llamaría debajo, pero la clase invocadora no sabe cuál. ¿Cómo saberlo? ¡No tiene instancias para adivinar eso!
Se pensaba que las interfaces se utilizaban al trabajar con objetos. De esta manera, un objeto se crea una instancia de una clase particular, por lo que este último asunto se resuelve. La clase que invoca no necesita saber qué clase en particular es porque la creación de instancias puede ser realizada por una tercera clase. Así que la clase invocadora solo conoce la interfaz.
Si queremos que esto se extienda a métodos estáticos, deberíamos tener la posibilidad de especificar una clase de implementación antes, luego pasar una referencia a la clase que invoca. Esto podría utilizar la clase a través de los métodos estáticos en la interfaz. ¿Pero cuál es la diferencia entre esta referencia y un objeto? Solo necesitamos un objeto que represente lo que era la clase. Ahora, el objeto representa la clase anterior, y podría implementar una nueva interfaz que incluya los métodos estáticos antiguos, que ahora no son estáticos.
Las metaclases sirven para este propósito. Puedes probar la clase Class de Java. Pero el problema es que Java no es lo suficientemente flexible para esto. No se puede declarar un método en el objeto de clase de una interfaz.
Este es un problema meta, cuando tienes que hacer el culo
.. blah blah
De todos modos, tiene una solución fácil: hacer que el método no sea estático con la misma lógica. Pero luego tendría que crear primero un objeto para llamar al método.
Una interfaz nunca se puede anular de forma estática, por ejemplo, ISomething.member
. Una interfaz siempre se anula a través de una variable que hace referencia a una instancia de una subclase de la interfaz. Por lo tanto, una referencia de interfaz nunca puede saber a qué subclase se refiere sin una instancia de su subclase.
Por lo tanto, la aproximación más cercana a un método estático en una interfaz sería un método no estático que ignora "esto", es decir, no accede a ningún miembro no estático de la instancia. En la abstracción de bajo nivel, cada método no estático (después de la búsqueda en cualquier vtable) es realmente una función con alcance de clase que toma "esto" como un parámetro formal implícito. Vea el objeto singleton de Scala y la interoperabilidad con Java como evidencia de ese concepto. Y así, cada método estático es una función con alcance de clase que no toma un parámetro "esto". Por lo tanto, normalmente un método estático puede llamarse estáticamente, pero como se indicó anteriormente, una interfaz no tiene implementación (es abstracta).
Por lo tanto, para obtener la aproximación más cercana a un método estático en una interfaz, es usar un método no estático, y luego no acceder a ninguno de los miembros de la instancia no estática. No habría ningún beneficio de rendimiento posible de ninguna otra manera, porque no hay manera de vincular estáticamente (en tiempo de compilación) un ISomething.member()
. El único beneficio que veo de un método estático en una interfaz es que no ingresaría (es decir, ignoraría) un "esto" implícito y, por lo tanto, no permitiría el acceso a ninguno de los miembros de la instancia no estática. Esto declararía implícitamente que la función que no accede a "esto" está inmutada y ni siquiera es de lectura con respecto a su clase contenedora. Pero una declaración de "estática" en una interfaz ISomething
también confundiría a las personas que intentaron acceder a ella con ISomething.member()
lo que provocaría un error de compilación. Supongo que si el error del compilador fuera suficientemente explicativo, sería mejor que tratar de educar a las personas sobre el uso de un método no estático para lograr lo que quieren (aparentemente en su mayoría métodos de fábrica), como lo estamos haciendo aquí (y se ha repetido durante 3 Preguntas y respuestas en este sitio), por lo que obviamente es un problema que no es intuitivo para muchas personas. Tuve que pensar en ello por un tiempo para obtener la comprensión correcta.
La forma de obtener un campo estático mutable en una interfaz es utilizar métodos getter y setter no estáticos en una interfaz, para acceder a ese campo estático que en la subclase. Además, las estadísticas aparentemente inmutables se pueden declarar en una interfaz Java con static final
.
Varias respuestas han discutido los problemas con el concepto de métodos estáticos reemplazables. Sin embargo, a veces te encuentras con un patrón en el que parece que eso es justo lo que quieres usar.
Por ejemplo, trabajo con una capa relacional de objetos que tiene objetos de valor, pero también tiene comandos para manipular los objetos de valor. Por varias razones, cada clase de objeto de valor tiene que definir algunos métodos estáticos que permiten al marco encontrar la instancia del comando. Por ejemplo, para crear una Persona que harías:
cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();
y para cargar una persona por ID harías
cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();
Esto es bastante conveniente, sin embargo tiene sus problemas; En particular, la existencia de los métodos estáticos no se puede imponer en la interfaz. Un método estático reemplazable en la interfaz sería exactamente lo que necesitaríamos, si tan solo pudiera funcionar de alguna manera.
Los EJB resuelven este problema al tener una interfaz de Inicio; Cada objeto sabe cómo encontrar su Hogar y el Hogar contiene los métodos "estáticos". De esta manera, los métodos "estáticos" pueden anularse según sea necesario, y no saturar la interfaz normal (se llama "Remoto") con métodos que no se aplican a una instancia de su bean. Simplemente haga que la interfaz normal especifique un método "getHome ()". Devuelva una instancia del objeto Inicio (que podría ser un singleton, supongo) y la persona que llama puede realizar operaciones que afecten a todos los objetos Person.
¿Cuál es la necesidad del método estático en la interfaz? Los métodos estáticos se usan básicamente cuando no tiene que crear una instancia de objeto. La idea de la interfaz es introducir conceptos OOP con introducción del método estático que está desviando del concepto.
Creo que Java no tiene métodos de interfaz estáticos porque no los necesitas. Puedes pensar que lo haces, pero ... ¿Cómo los usarías? Si quieres llamarlos como
MyImplClass.myMethod()
entonces no es necesario declararlo en la interfaz. Si quieres llamarlos como
myInstance.myMethod()
entonces no debería ser estático. Si realmente va a utilizar la primera forma, pero solo desea imponer que cada implementación tenga un método estático, entonces es realmente una convención de codificación, no un contrato entre la instancia que implementa una interfaz y un código de llamada.
Las interfaces le permiten definir el contrato entre la instancia de la clase que implementa la interfaz y el código de llamada. Y java te ayuda a asegurarte de que este contrato no se haya violado, por lo que puedes confiar en él y no preocuparte de qué clase implementa este contrato, solo "alguien que firmó un contrato" es suficiente. En caso de interfaces estáticas su código.
MyImplClass.myMethod()
no confía en el hecho de que cada implementación de interfaz tenga este método, por lo que no necesita Java para ayudarlo a estar seguro con él.
Why can''t I define a static method in a Java interface?
Todos los métodos en una interfaz son explícitamente abstractos y, por lo tanto, no puede definirlos como estáticos porque los métodos estáticos no pueden ser abstractos.
- "¿Hay alguna razón particular por la que los métodos estáticos no pueden ser anulados".
Permítanme reformular esa pregunta para usted completando las definiciones.
- "Hay una razón particular por la que los métodos resueltos en tiempo de compilación no pueden resolverse en tiempo de ejecución".
O, para poner más completamente, si quiero llamar a un método sin una instancia, pero conociendo a la clase, ¿cómo puedo resolverlo en función de la instancia que no tengo?