2015-01-11 11 views
11

Ho una classe astratta e una classe che la estendono, ho un metodo con lo stesso nome in entrambe le classi. Voglio chiamare il metodo in classe astratta in un altro metodo di classe astratta.Metodo di chiamata da un altro metodo in classe astratta con lo stesso nome nella classe reale

Controller.java

public abstract class Controller { 

    public Result delete(Long id) { 
     return this.delete(id, true); 
    } 
    public Result delete(Long id, boolean useTransaction) { 
     // do something and return result 
    } 
} 

FileGroup.java

public class FileGroup extends Controller { 

    public Result delete(Long id, boolean central) { 
     // do something 
     return super.delete(id); 
    } 
} 

super.delete chiamata Controller.delete ma this.delete(id, true) chiamata delete in FileGroup invece di chiamare delete in Controller che sta causando ricorsiva ciclo infinito e lo stack overflow.

+0

@aioobe Non è del tutto chiaro. Perché l'OP non ha scritto 'super.delete (id, central)'? Può essere che l'OP voglia effettivamente 'delete' in' FileGroup' per chiamare l'argomento 'delete' in Controller che a sua volta chiama i due argomenti' delete' in 'Controller' senza causare un loop infinito. –

+0

* "Perché l'OP non ha scritto super.delete (id, centrale)?" * - Perché quello sarebbe un override inutile. * "[...] senza causare un loop infinito." * - Sì, è quello che assumerei (ed è quello che indirizzo nella mia risposta). – aioobe

+1

Non sarebbe un override inutile a causa del "// fare qualcosa". –

risposta

7

[...] ma this.delete(id, true) chiamata cancellare in FileGroup invece di chiamare cancellare in Controller.

Sì, tutti i metodi sono virtuali in Java e non c'è modo di evitarlo. tuttavia è possibile aggirare questo creando un (non override) helper nella Controller come segue:

public abstract class Controller { 

    private Result deleteHelper(Long id, boolean useTransaction) { 
     // do something and return result 
    } 

    public Result delete(Long id) { 
     return deleteHelper(id, true); 
    } 
    public Result delete(Long id, boolean useTransaction) { 
     return deleteHelper(id, useTransaction); 
    } 
} 

In questo modo si evita di dover Controller.delete delegato la chiamata alla sottoclasse.

+0

grazie per la risposta Sono d'accordo con te, ma c'è qualcosa di simile a 'questo' per menzionare la classe corrente, se fosse statico posso semplicemente chiamare Controller :: delete (id, true) –

+1

No. Devi fare questo tipo di soluzione alternativa. – aioobe

3

Non è del tutto chiaro quale sia la tua domanda. Se si sta solo cercando di rendere il metodo delete nel FileGroup chiamata al metodo delete(id, true) in Controller senza causare un overflow dello stack, si può semplicemente fare questo:

public class FileGroup extends Controller { 

    public Result delete(Long id, boolean central) { 
     // do something 
     return super.delete(id, true); 
    } 
} 

Se la tua domanda è come fare il metodo one-argomento delete in Controller chiamare il metodo delete a due argomenti in Controller anziché la versione in FileGroup, la risposta è che è necessario utilizzare la soluzione del metodo helper di @ aioobe.

+0

grazie per la risposta risolverebbe il mio problema ma vorrei davvero sapere che c'è qualcosa come 'questo' per menzionare la classe corrente, se fosse statico posso semplicemente chiamare Controller :: delete (id, true) –

+1

@MohseTaheri Non c'è modo di invocare un metodo di istanza nella classe 'this' e impedire l'esecuzione di versioni in sottoclassi. La funzionalità sarebbe comunque inutile. Come per definizione hai il controllo della classe corrente, puoi sempre usare la soluzione di aioobe - chiama invece un metodo privato (o finale) da questa classe. –

Problemi correlati