2015-05-05 17 views
5

Mam metodę String foo() w klasie abstrakcyjnej, która wykonuje już kilka obliczeń, ale nie może dostarczyć końcowego wyniku, który metoda ma zwrócić. Tak więc chcę, aby każda nie abstrakcyjna klasa dziedzicząca z mojej abstrakcyjnej klasy musiała implementować foo w sposób, w jaki jest wywoływana pierwsza super(), a następnie obliczany jest wynik. Czy istnieje sposób, aby zmusić to w java?Wymuszenie zastąpienia metody nie abstrakcyjnej

+0

proszę podzielić podpis metody dla foo –

+1

Czy to nazwać abstrakcyjną metodę, która musi albo wykonać ostateczne obliczenia lub wartość (y) return że musi – MadProgrammer

Odpowiedz

15

Tak, przez przeprojektowanie używać template method pattern włącznie abstrakcyjną metodę:

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

Zasadniczo, jeśli chcesz wymusić podklasy zastąpić metodę, to robi muszą być abstrakcyjne - ale to nie robi” t musi być metodą, która jest wywoływana przez inny kod ...

+0

Czy istnieje konwencja, w jaki sposób wywołać na dwa sposoby? Nadałbym im to samo imię (co oczywiście nie jest możliwe), ponieważ w zasadzie robią to samo. –

+0

@ principal-ideal-domain Czy oni? Metoda "abstrakcyjna" wykonuje inną część całego obliczenia, więc powinna mieć odpowiednią nazwę. Ta sama nazwa może powodować pewne nieporozumienia dotyczące sposobu implementacji metody abstrakcyjnej w klasie potomnej. – Tom

+0

@Tom Tak, to prawda. Wykonuje inną część. Ale zwykle nazywam swoje metody tym, co powracają, a nie tym, co robią. Na przykład w moim obecnym przypadku chcę tylko policzyć liczbę wywołań metod, więc moje 'foo' wygląda jak' counter ++; pasek powrotu(); '. Przy okazji: Czy można zabronić wywoływania abstrakcyjnej metody w klasach, które ją implementują? –

4

Nie ma sposobu, aby to zrobić w Javie. Możesz jednak zadeklarować jeszcze jedną metodę, która jest abstrakcyjna i wywołaj ją. Tak:

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

protected abstract String calculateFinalResult(String intermediate); 

ten sposób będziesz zmuszony zastąpić calculateFinalResult. Nie jest wymagane wywoływanie instancji super. Również podklasy nie będą w stanie przedefiniować twojego foo(), ponieważ jest zadeklarowany jako final.

+1

Uwaga: dobrze jest użyć odpowiedniego sortowania modyfikatorów (np. 'Protected' i' abstract'). Zalecane sortowanie można znaleźć tutaj: https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s4.8.7-modyfikatory. – Tom

3

Coś takiego?

public abstract class MyBean { 

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

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

Dobrym pomysłem może być zmiana modyfikatora 'doFinalResult' z' public' na 'protected', więc inne klasy (z wyjątkiem klas potomnych i klas w tym samym pakiecie) nie będą miały do ​​niego bezpośredniego dostępu. – Tom

Powiązane problemy