2013-10-12 11 views
7

Diciamo che ho queste due classi, una estendendo l'altraAvvisa sviluppatore di chiamare `super.foo()` in java

public class Bar{ 

    public void foo(){ 

    } 

} 

public class FooBar extends Bar { 

    @Override 
    public void foo(){ 
     super.foo(); //<-- Line in question 
    } 

} 

Quello che voglio fare è avvisare l'utente alla chiamata del super-class metodo foo se non hanno il metodo di override, è possibile?

O c'è un modo per sapere, usando la riflessione che un metodo che sovrascrive un metodo della sua super-classe chiama il metodo originale se passo il tipo di classe al super?

ad esempio:

public abstract class Bar{ 

    public Bar(Class<? extends Bar> cls){ 
     Object instance = getInstance(); 
     if (!instance.getClass().equals(cls)) { 
      throw new EntityException("The instance given does not match the class given."); 
    } 
     //Find the method here if it has been overriden then throw an exception 
     //If the super method isn't being called in that method 
    } 

    public abstract Object getInstance(); 

    public void foo(){ 

    } 

} 

public class FooBar extends Bar { 

    public FooBar(){ 
     super(FooBar.class); 
    } 

    @Override 
    public Object getInstance(){ 
     return this; 
    } 

    @Override 
    public void foo(){ 
     super.foo(); 
    } 

} 

Forse anche un'annotazione posso mettere sul metodo eccellente in modo che dimostra che ha bisogno di essere chiamato?


EDIT

Nota, non è il super classe che ha bisogno di chiamare il metodo foo, sarebbe qualcuno che chiama il metodo foo della classe secondaria, ad esempio, un metodo di database close

Sarei anche contento di rendere il metodo "non trascurabile" se ci si avvicina, ma vorrebbe comunque dargli un messaggio personalizzato.


Edit 2

Questo qui è quello che volevo in un modo:

enter image description here

ma sarebbe comunque bello avere quanto sopra, o anche dare loro un messaggio personalizzato per fare qualcos'altro come, Cannot override the final method from Bar, please call it from your implementation of the method instead

+1

Questo potrebbe essere possibile con un codice statico strumento di analisi/controllo delle regole (ad es. IDEA). Probabilmente non dovrebbe essere fatto in fase di esecuzione (ad esempio con la riflessione). – user2864740

+1

Se non è possibile utilizzare il modello di modello, FindBugs ha un'annotazione che rileva le sostituzioni mancanti: [OverrideMustInvoke] (http://findbugs.sourceforge.net/manual/annotations.html) –

+0

* Sarei persino felice di creare metodo "non sovrascrivibile" *: questo è il significato di 'final'. –

risposta

4

MODIFICA: Per rispondere alla modifica, domanda , Che comprende:

Vorrei anche essere felice con fare il metodo "un ignorabile"

... basta fare il metodo final. Ciò impedirà alle sottoclassi di sovrascriverlo. Da section 8.4.3.3 of the JLS:

Un metodo può essere dichiarato final per impedire alle sottoclassi di sostituire o di nasconderlo.

Si tratta di un errore in fase di compilazione per tentare di ignorare o nascondere un metodo final.

Per rispondere alla domanda iniziale, è consigliabile utilizzare il template method pattern invece:

public abstract class Bar { 
    public foo() { 
     // Do unconditional things... 
     ... 
     // Now subclass-specific things 
     fooImpl(); 
    } 

    protected void fooImpl(); 
} 

public class FooBar extends Bar { 
    @Override protected void fooImpl() { 
     // ... 
    } 
} 

Ciò non forzare sottoclassi di FooBar per ignorare fooImpl e chiamare super.fooImpl() ovviamente - ma FooBarpotrebbe farlo applicando di nuovo lo stesso modello, rendendo definitiva la sua implementazione fooImpl e introducendo un nuovo metodo astratto protetto.

+0

Controlla la modifica, penso che usare l'ultima potrebbe farlo – FabianCook

+0

@SmartLemon: Beh sì, se cambi completamente i requisiti, 'finale' lo farebbe davvero ... –

+0

Spiacente, controlla la seconda modifica, l'originale è ancora parte della domanda. – FabianCook

0

quello che si potrebbe fare è qualcosa di simile seguente metodo

public class Bar{ 

    public final void foo(){ 
     //do mandatory stuff 
     customizeFoo(); 
    } 

    public void customizeFoo(){ 

    } 

} 

public class FooBar extends Bar { 

    @Override 
    public void customizeFoo(){ 
     //do custom suff 
    } 

} 

foo fatto 'finale' in superclasse in modo che le sottoclassi non possono ignorare ed evitare di fare cose obbligatoria

Problemi correlati