2011-02-10 19 views
26

Tengo una pregunta rápida y straighforward:Polimorfismo y sobrecarga de métodos

tengo esta clase simple:

public class A 
{ 
    public void m(Object o) 
    { 
     System.out.println("m with Object called"); 
    } 

    public void m(Number n) 
    { 
     System.out.println("m with Number called"); 
    } 
    public static void main(String[] args) 
    { 
     A a = new A(); 
     // why will m(Number) be called? 
     a.m(null); 
    } 
} 

ACTUALIZACIÓN: en realidad es el método con el número realmente ser llamado. Perdón por la confusión.

Si llamo a.m (nulo), llama al método con el parámetro Número.

Mi pregunta es: ¿por qué es esto? donde en la especificación del lenguaje java se especifica esto?

+1

... porque 'null' no es un objeto' Number', por lo que cae en el depósito 'Object' más generalizado. – limc

+5

eso es gracioso porque en mi máquina (ejecutándolo en eclipse) siempre está predeterminado al método Número –

+1

+1 pregunta interesante –

Respuesta

27

En primer lugar, realmente llama a m(Number).

Esto sucede porque ambos métodos son aplicables , pero es m(Number) el método más específico, ya que cualquier argumento de m(Number) se puede pasar a m(Object), pero no viceversa.

Si reemplaza por m(Object)m(String) (o añadir otro método como m(Date)), compilador reportar ambigüedad, ya que el método más específico no puede ser identificado.

Consulte la sección Choosing the Most Specific Method en la Especificación de Java.

+2

bien, ahora que realmente he ejecutado el código de ejemplo, veo esto también. También tiene sentido que una vez que agregué m (Date n) {...} obtuve un error: "el método m (Object) es ambiguo para el tipo" – David

0

Object es el tipo predeterminado en Java. Si refactoriza su método de m(Object o) a m(String o) tendrá un error de tiempo de compilación diciendo que la llamada m(null) es ambiguo porque Java no puede determinar qué clases entre String y Number defecto null

Aparte de eso, entre m(Object o) y m(Number o), llamando m(null) llamará al m(Number o) porque es el método más especializado. Necesitaría convertir null en un Object (o cualquier cosa que no sea una instancia de Number) de lo contrario.

a.m((String) null); 
+0

nulo no tiene ningún tipo y lo llama m (Número) –

+0

bien .. formalmente hay un tipo nulo, y es un subtipo de todos los tipos de referencia. bastante raro. – irreputable

12
  1. Esto no es polimorfismo ni anula. Este es el método que sobrecarga.
  2. He probado esto y se está llamando a un método específico (no el m (Objeto)) y de acuerdo con la especificación se llama siempre al método específico. Which overload will get selected for null in Java?
+2

+1 para notar la diferencia entre anular y sobrecargar –

+0

+1 para resaltar que esto está sobrecargando –

1

Mi 2 centavos. El método con el argumento número es el que se llama, porque el número extiende el objeto. Tuve una situación similar en el pasado, anulé un método y puse Component en lugar de JComponent (por error). Me tomó una semana averiguar la razón por la cual nunca se llamó mi método. Me doy cuenta de que si hay alguna relación de herencia entre los métodos sobrecargados, la JVM coincide primero con la más profunda en la jerarquía de clases.

7

otra pregunta relacionada para que usted pueda pensar:

public static void main(String[] args) 
{ 
    A a = new A(); 
    Object n = new Integer(1); 
    a.m(n); // which method will be called? 
} 
+0

se llamará "m con Objeto llamado" pero no sé por qué. ¿Alguien puede explicar? Intuitivamente, pensé que se imprimiría "m with Number called", pero ... noooooo. – IsenGrim

0

Jaguar, According to the Java Specifications, sí, es un objeto. Entonces, el método elegido para a.m (verdadero) en el principal recurre al tipo de parámetro Object.

Boolean se define en java.lang.Boolean Número se define en Java.lang.Number

(Ambos extender objeto)

libro codificadores Rhyme: "Cuando en vex, referencia de las especificaciones"

Cuestiones relacionadas