2015-05-05 15 views
5

Ho un metodo String foo() in una classe astratta che già esegue alcune precomputazioni ma non è in grado di fornire il risultato finale che si suppone che il metodo restituisca. Quindi quello che voglio è che ogni classe non astratta che eredita dalla mia classe astratta deve implementare foo in un modo che viene chiamato prima super() e quindi il risultato è calcolato. C'è un modo per forzare questo in Java?Forza il metodo non astratto da sovrascrivere

+0

si prega di condividere la firma del metodo per foo –

+1

, farla chiamare un metodo astratto che deve sia eseguire i calcoli finali o valore di ritorno (s) che ha bisogno di – MadProgrammer

risposta

15

Sì, ridisegnando di utilizzare la template method pattern e comprendente un metodo astratto:

public abstract class AbstractSuper { 
    public final String foo() { 
     // Maybe do something before calling bar... 
     String initialResult = bar(); 
     // Do something common, e.g. validation 
     return initialResult; 
    } 

    protected abstract String bar(); 
} 

In pratica se si vuole forzare sottoclassi per scavalcare un metodo, fa devono essere astratto - ma che doesn' t deve essere il metodo che viene chiamato da altro codice ...

+0

C'è un convegno su come chiamare i due metodi? Darei loro lo stesso nome (che ovviamente non è possibile) perché fondamentalmente fanno la stessa cosa. –

+0

@ principal-ideal-domain Lo fanno? Il metodo 'abstract' esegue una parte diversa dell'intero calcolo, quindi dovrebbe avere un nome corrispondente. Lo stesso nome potrebbe causare qualche incomprensione su come implementare il metodo astratto in una classe figlia. – Tom

+0

@ Tom Sì, è vero. Esegue una parte diversa. Ma di solito chiamo i miei metodi da ciò che restituiscono e non da ciò che fanno. Per esempio nel mio caso attuale voglio solo contare il numero di chiamate al metodo, quindi il mio 'foo' sembra' counter ++; barra di ritorno(); '. A proposito: è possibile proibire la chiamata del metodo astratto nelle classi che la implementano? –

4

Non c'è modo di farlo in Java. Comunque puoi dichiarare un altro metodo che è astratto e chiamalo. Come questo:

public final String foo() { 
    String intermediate = ... // calculate intermediate result; 
    return calculateFinalResult(intermediate); 
} 

protected abstract String calculateFinalResult(String intermediate); 

In questo modo si sarà costretti a ignorare calculateFinalResult. Non è necessaria alcuna chiamata dell'istanza super. Anche le sottoclassi non saranno in grado di ridefinire il tuo foo() come dichiarato come final.

+1

Solo una nota: è una buona idea usare un adeguato ordinamento dei modificatori (ad esempio 'protected' e' abstract'). Puoi trovare l'ordinamento consigliato qui: https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s4.8.7-modificatori. – Tom

3

Qualcosa di simile?

public abstract class MyBean { 

    public final String foo(){ 
     String preFinalResult = [...]; 
     return doFinalResult(preFinalResult) 
    } 

    protected abstract String doFinalResult(String preFinal); 
} 
+1

Potrebbe essere una buona idea cambiare il modificatore di 'doFinalResult' da' public' a 'protected', così le altre classi (tranne le classi e le classi figlio nello stesso pacchetto) non possono accedervi direttamente. – Tom

Problemi correlati