2012-11-09 16 views

risposta

24

Questo perché il compilatore non sarebbe in grado di calcolare il sovraccarico in tutti i contesti.

Ad esempio, se si chiama

String x = method1("aaa"); 

il compilatore sa che si sta cercando per il secondo sovraccarico. Tuttavia, se si chiama

method1("aaa"); 

come questo, il compilatore non ha idea che uno dei due metodi si voleva richiamare, perché è OK per chiamare un metodo che restituisce String e scartare il risultato. Per evitare ambiguità come questa, Java proibisce sovraccarichi che differiscono unicamente sul tipo di ritorno.

3

Non si può sovraccaricare un metodo solo su di esso la tipo di ritorno. È semplicemente illegale. Supponiamo per un momento che i metodi di overload che utilizzano il tipo restituito siano legali e sono stati definiti due metodi method1. Ora vogliamo chiamare ciò che restituisce il String object:

String string = method1(sth);

La JVM in teoria sarebbe in grado di riconoscere quale metodo si in questione, destinate a chiamare, ma per quanto riguarda tale chiamata:

method1(sth);

Come puoi vedere, entrambi i metodi potrebbero essere richiamati e tali operazioni non sono ambigue. La JVM non sa quale metodo dovrebbe chiamare. Questo è il motivo per cui tale sovraccarico è vietato.

+0

+1 per la risposta. – Raghunandan

+5

Non puoi perché non puoi? Veramente? – m3th0dman

+0

Ho spiegato che in edit;) Ho inviato un post breve perché scrivere le risposte a domande così semplici è come una gara, quindi se è possibile rimuovere il tuo voto. –

0

è possibile chiamare la funzione come procedura: method1("arg"); dove method1 è il secondo metodo nell'elenco (String method1(String arg){}). Il compilatore quindi non sarebbe in grado di distinguerlo dal primo (void method1(String arg){}).

1

Poiché è impossibile risolvere quale dei metodi di overload dovrebbe essere chiamato in un caso come questo:

public static void main(String... args) { 
    method1("aaa"); 
} 
-1

Methode sovraccarico viene controllato sulla base del numero e tipo di argomenti non sulla base di ritorno tipo. Questo è il motivo per cui stai ricevendo errore.

+0

La domanda è: perché quell'errore. –

+0

Poiché si tratta di un tentativo di definire due metodi con la stessa firma. Che viene verificato nella tabella dei metodi e non è consentito. –

+0

Perché non è permesso? –

3

Poiché la tua domanda non si riferisce ad alcun particolare linguaggio di programmazione nel titolo (lo so che fa nel tag) condividerò la mia recente esperienza con Swift. In Swift la funzione/firma del metodo include effettivamente il tipo restituito. Così compilatore genera un errore solo se si chiama questa funzione/metodo senza specificare esplicitamente tipo di ritorno, ad es .:

func some() -> Bool { 
    return true; 
} 

func some() -> Int { 
    return 1; 
} 

let valBool: Bool = some() 
let valInt: Int = some() 

// this doesn't work: Ambiguous use of 'some' 
some() 

In cima a questo Swift ancora lo rende più interessante. Ti consente di avere 2 funzioni/metodi con gli stessi parametri e tipi di ritorno solo se i nomi dei parametri sono diversi, ad es.:

func some(#foo: Bool) -> Bool { 
    return foo; 
} 

func some(#bar: Bool) -> Bool { 
    return bar; 
} 

some(foo: true) 
some(bar: false) 

Così ti dà differenziazione semantica nei metodi di firma

UPD. Dal momento che Swift 2.0 esterno nome del parametro è stato cambiato e ora è necessario fornire i nomi esterni e locali due volte anche se è lo stesso

func some(foo foo: Bool) -> Bool { 
    return foo; 
} 

func some(bar bar: Bool) -> Bool { 
    return bar; 
} 

some(foo: true) 
some(bar: false) 
+0

+1 per una prospettiva più ampia quindi java. Sarebbe interessante sentire la tua opinione sul fatto che la convenienza accumulata superi i problemi associati a questa scelta.Immagino per i tipi di ritorno semplici che non contano molto, ma per gli oggetti questo potrebbe consentire il riutilizzo delle risorse delle variabili di output ... e quindi non ti permette di ignorare facilmente il valore di ritorno che vedo come una caratteristica non un trambusto. – Slava

0

Ci sono diversi punti da considerare nella progettazione di cose come la risoluzione di sovraccarico.

motivi per omettere sovraccarico sul tipo di ritorno:

  1. Semplificare ignorando il valore di ritorno della funzione (come le persone fanno spesso con i codici di errore).
  2. Rende il programma più facile da digerire per i lettori umani. In particolare, questa è la ragione per cui in Python non hanno affatto sovraccarichi di funzione. (questione di gusti)
  3. C legacy. Quando la lingua viene da C-famiglia e progettisti non considerano qualcosa di cui essere un grosso problema che viene lasciato come è sempre stato ...

ragioni per aggiungere sovraccarico sul tipo di ritorno:

  1. Marchio è difficile ignorare i valori restituiti. Questo può essere conveniente e consente di risparmiare un po 'di digitazione, ma sicuramente ti morderà un giorno.
  2. Espressività (ovviamente in contrasto con la facilità di digerire :)). Hai mai desiderato scrivere cose come int x = json.get("int_value"); float y = json.get("float_value");? In alcuni linguaggi (come C++) che è ancora possibile ottenere con i proxy e gli operatori cast, ma il sovraccarico sul tipo restituito sarebbe molto più semplice.
  3. Espressività. Ogni volta che si passa il valore di retun come riferimento alla propria funzione solo per riutilizzare le sue risorse questo potrebbe essere un sovraccarico sul tipo restituito (con il parametro nascosto simile). Si consideri string s; getline(cin, s); vs string s = getline(cin);. Ed è qui che l'espressività si unisce alla trasparenza referenziale e, alla fine, alla facilità di digerire il codice.

Ora torna alla tua domanda "perché?". Dal momento che stavi chiedendo di Java, la risposta è ovviamente perché James ha apprezzato i motivi per omettere i sovraccarichi di tipo restituito sui motivi per includerli nella lingua.

Problemi correlati