2011-02-10 2 views
26

Ho una domanda veloce e straighforward:Polimorfismo e metodo di sovraccarico

ho questo semplice classe:

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); 
    } 
} 

UPDATE: in realtà è il metodo con il numero in realtà essere chiamato. Mi dispiace per la confusione.

Se chiamo a.m (null) chiama metodo con parametro Number.

La mia domanda è: perché è questo? dove sono specificate le specifiche del linguaggio Java?

+1

... perché 'null' non è un oggetto' Numero', quindi rientra nel secchio 'Object' più generalizzato. – limc

+5

è divertente perché sul mio computer (eseguendolo su eclipse) è sempre impostato sul metodo Numero –

+1

+1 domanda interessante –

risposta

27

Prima di tutto, in realtà chiama m(Number).

Succede perché entrambi i metodi sono applicabili , ma m(Number) è il metodo più specifico, poiché qualsiasi argomento m(Number) può essere passato a m(Object), ma non viceversa.

Se si sostituisce m(Object) da m(String) (o aggiungere un altro metodo come m(Date)), compilatore segnalare l'ambiguità, dal momento che il metodo più specifico non può essere identificato.

Vedere la sezione Choosing the Most Specific Method nella specifica Java.

+2

ok, ora che ho effettivamente eseguito il codice di esempio, vedo anche questo. Ha anche senso che una volta ho aggiunto m (Data n) {...} che ho ricevuto un errore: "il metodo m (Object) è ambiguo per il tipo" – David

0

Object è il tipo predefinito in Java. Se si refactoring il metodo m(Object o)-m(String o) avrete un errore in fase di compilazione dicendo che la chiamata m(null) è ambiguo perché Java non può determinare quale classe tra String e Number default null

Oltre a questo, tra il m(Object o) e m(Number o), chiamando m(null) chiamerà m(Number o) perché è il metodo più specializzato. Avresti bisogno di trasmettere null in un Object (o qualsiasi altra cosa non sia un'istanza di Number) altrimenti.

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

null non ha tipo e chiama m (Numero) –

+0

bene .. .. formalmente c'è un tipo nullo, ed è un sottotipo di tutti i tipi di riferimento. abbastanza strano. – irreputable

12
  1. Questo non è polimorfismo o override. Questo è il metodo sovraccarico.
  2. Ho provato questo metodo e viene chiamato il metodo specifico (non il m (Object)) e in base alle specifiche viene sempre chiamato il metodo specifico. Which overload will get selected for null in Java?
+2

+1 per notare la differenza tra override e overloading –

+0

+1 per evidenziare che questo è sovraccarico –

1

I miei 2 centesimi. Il metodo con l'argomento Number è quello chiamato, perché Number estende Object. Ho avuto una situazione simile in passato, ho sovrascritto un metodo e ho inserito Component al posto di JComponent (per errore). Mi ci è voluta una settimana per scoprire il motivo per cui il mio metodo non è mai stato chiamato. Immagino che se ci sono alcune relazioni di ereditarietà tra i metodi sovraccaricati, la JVM corrisponde prima alla più profonda nella gerarchia delle classi.

7

un'altra domanda relativa per voi di pensare:

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

"m con oggetto chiamato" verrà chiamato ma non so perché. Qualcuno può spiegare? Intuitivamente, ho pensato che "m with Number called" verrà stampato, ma ... noooooo. – IsenGrim

0

Jaguar, According to the Java Specifications, sì, è un oggetto. Quindi il metodo scelto per a.m (true) nei resort principali per il tipo di parametro Object.

booleana è definita java.lang.Boolean numero è definito in Java.lang.Number

(Sia estendere oggetto)

Coders Rhyme libro: "Quando nel vex, riferimento alle specifiche"