2015-05-05 22 views
5

ich eine Methode String foo() in einer abstrakten Klasse haben, die schon ein paar Vorberechnung tut aber das Endergebnis nicht liefern das Verfahren soll zurückzukehren. Was ich will, ist, dass jede nicht abstrakte Klasse, die von meiner abstrakten Klasse erbt, foo so implementieren muss, dass zuerst super() aufgerufen wird und dann das Ergebnis berechnet wird. Gibt es eine Möglichkeit, dies in Java zu erzwingen?Kraft nicht abstrakte Methode werden außer Kraft gesetzt

+0

bitte die Methodensignatur für foo teilen –

+1

Haben sie eine abstrakte Methode aufrufen, die die endgültigen Berechnungen oder Rückgabewert (e) zu muss entweder durchführen, die es braucht – MadProgrammer

Antwort

15

Ja, durch die Neugestaltung der template method pattern und darunter eine abstrakte Methode zu verwenden:

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

Grundsätzlich, wenn Sie Subklassen erzwingen wollen, um eine Methode zu überschreiben, es tut abstrakt sein - aber das doesn‘ t muss die Methode sein, die von anderem Code aufgerufen wird ...

+0

Gibt es eine Konvention, wie die beiden Methoden nennen? Ich würde ihnen den gleichen Namen geben (was natürlich nicht möglich ist), weil sie im Prinzip dasselbe tun. –

+0

@ principal-ideal-domain Sind sie? Die Methode "abstract" führt einen anderen Teil der gesamten Berechnung aus, daher sollte sie einen entsprechenden Namen haben. Derselbe Name könnte zu Missverständnissen bei der Implementierung der abstrakten Methode in einer untergeordneten Klasse führen. – Tom

+0

@Tom Ja, das stimmt. Es führt einen anderen Teil durch. Aber normalerweise rufe ich meine Methoden nach dem, was sie zurückgeben, und nicht nach dem, was sie tun. Zum Beispiel möchte ich in meinem aktuellen Fall nur die Anzahl der Methodenaufrufe zählen, so dass mein 'foo' wie' counter ++; Rücksprungleiste(); '. Übrigens: Ist es möglich, den Aufruf der abstrakten Methode in den Klassen zu verbieten, die sie implementieren? –

4

Es gibt keine Möglichkeit, dies in Java zu tun. Sie können jedoch eine weitere abstrakte Methode deklarieren und aufrufen. Wie folgt aus:

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

protected abstract String calculateFinalResult(String intermediate); 

So kann man gezwungen sein, calculateFinalResult außer Kraft zu setzen. Kein Aufruf von super Instanz ist notwendig. Auch Unterklassen können Ihre foo() nicht so definieren, wie sie als final deklariert ist.

+1

Nur eine Anmerkung: Es ist eine gute Idee, eine geeignete Sortierung der Modifikatoren (z. B. "geschützt" und "abstrakt") zu verwenden. Sie finden eine empfohlene Sortierung hier: https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s4.8.7-modifiers. – Tom

3

So ähnlich?

public abstract class MyBean { 

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

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

Es könnte eine gute Idee sein, den Modifikator 'doFinalResult' von' public' in 'protected' zu ändern, damit andere Klassen (außer Kindklassen und Klassen im selben Paket) nicht direkt darauf zugreifen können. – Tom

Verwandte Themen