2011-04-08 19 views
7

Soy nuevo en Java Programming. ¿Puede alguien explicarme por qué el programa genera "fa la" aunque el método estático está anulado? Leí que los métodos estáticos no pueden ser anulados en Java? Por favor, corríjame si estoy equivocado.Métodos estáticos en Java

public class Tenor extends Singer { 
    public static String sing() { 
     return "fa"; 
    } 
    public static void main(String[] args) { 
     Tenor t = new Tenor(); 
     Singer s = new Tenor(); 
     System.out.println(t.sing() + " " + s.sing()); 
    } 
} 
class Singer { 
    public static String sing() { 
     return "la"; 
    } 
} 

Respuesta

4

Se debe acceder a los métodos estáticos con el nombre de clase y no con una referencia de objeto. La correcta equivalente de lo que escribió sería:

System.out.println(Tenor.sing() + " " + Singer.sing()) 

Java es adivinando inferir qué método destinado a invocar en función del tipo de objeto variable.

EDITAR: Como Stephen señaló, no es adivinar. Inferir probablemente sería una palabra más precisa. Solo estaba tratando de enfatizar que llamar a funciones estáticas en las referencias a objetos podría resultar en un comportamiento que no esperarías. De hecho, probé algunas cosas y descubrí que mi declaración anterior era incorrecta: Java decide qué método llamar en función del tipo de variable. Esto es obvio ahora que lo pienso más, pero puedo ver cómo se podría llevar a confusión si se hizo algo como:

Singer s = new Tenor(); 
System.out.println(s.sing()); 
+2

Java no * adivina * nada. El significado de una llamada a un método estático se especifica claramente en el JLS, junto con el hecho de que los métodos estáticos no se anulan. –

4

t es de tipo Tenor y s es de tipo Singer.

Cuando invoca un método estático en una instancia (lo cual es una mala práctica) está invocando el método estático en la clase del tipo declarado.

decir t.sing() es equivalente a Tenor.sing()

+1

Solo pensé en mencionar que probé un código y sorprendentemente 'Singer s = null; s.sing() 'funciona bien. ¿Te imaginas ver eso en código y que funcione inexplicablemente? – takteek

+0

Gracias, actualicé la respuesta. – Synesso

12

No se puede reemplazar los métodos estáticos en Java. Simplemente llama a los métodos estáticos directamente en cada clase. Por cierto: como otros han notado, se considera una mala práctica llamar a los métodos estáticos en las instancias. Para mayor claridad, se debe hacer lo siguiente:

System.out.println(Tenor.sing() + " " + Singer.sing()); 

que es equivalente al código que ha escrito en su pregunta.

+0

Si mal no recuerdo, llamar a un método estático en una instancia debería producir una advertencia de compilación ... –

2

Los métodos estáticos son no reemplazados. Pertenecen a la clase en la que están definidos. Llamar a un método estático en una instancia de ese método funciona de la misma manera que llamarlo a la clase, pero deja las cosas menos claras y hace que las personas piensen que están anuladas como métodos de instancia.

0

El código que escribió funciona bien, pero probablemente no como lo intentaste. Los métodos estáticos no pueden anularse en el sentido tradicional (o con el comportamiento que cabría esperar). En términos de qué versión del método se invoca, esto se hace en tiempo de compilación, que explica el resultado que ve.

Sí, y probablemente solo deba invocar los métodos utilizando el nombre de clase.

Cuestiones relacionadas