Using superclass "protected final" methods to keep common code for subclasses
Solution 1
If you're a Java beginner, or you are thinking about these sorts of things, then now is a good time to read the "Classes and Interfaces" chapter in a book called "Effective Java." The information there will be more thorough and nuanced than answers that you get here.
Here's one way to think about mixing the final
, protected
, and static
keywords:
- OO purists will advise you to avoid
static
because it breaks the OO paradigm. - Of course, using the
final
keyword prevents subclasses from overriding a method as well. In this respect, the outcome is the same as withstatic
. final
should be used more often, and it's a good idea to use it along withprotected
. See Item 17 in "Effective Java".protected
andstatic
are not used together very often. You'd be mixing an OO construct with a construct that breaks normal OO behavior, so the combination is odd.
Solution 2
It seems reasonable to me - although you might want to make A
abstract as well. Also consider using composition instead - could B
and C
contain an A
instead of subclassing it?
Solution 3
Firstly, you shouldn't use extends to this purpose because too much extending are always bad idea.
Secondly, You're completely right that you don't repeat your code, but grouping it by repeated part of code isn't good choice. Preferable way is to grouping things be meaning in real world, by level of abstraction.
Last but not least, When you have doubts: separately or not, extending or composition, protected final or only protected, try write unit test to this class and answers will come very fast.
dmzkrsk
Updated on June 03, 2022Comments
-
dmzkrsk about 2 years
As a (pedantic) beginner Java programmer I would like to know, is it a good practice to move a common block of code that all subclasses use to a separate protected (final) method in parent class? Tasks like filling lists with common values, or common filtering algorithms, etc... Is it good to also use protected static methods?
class A { protected final List<String> getVariants() {...} protected final List<String> filterResults(List<String> variants) {...} } class B extends A { public List<String> doSomethingUsefull() { List<String> commonVariants = getVariants(); ... return filterResults(commonVariants); } } class C extends A { public void doSomethingUsefull() { List<String> commonVariants = getVariants(); ... return filterResults(commonVariants); } public void doMoreUsefullThings() { List<String> commonVariants = getVariants(); ... return filterResults(commonVariants); } }
-
Guillaume over 12 yearsComposition over inheritance! Far easier to test, +1
-
dmzkrsk over 12 yearsSeems like that can work pretty well in my case. I'm gonna try that!
-
PhiLho over 11 yearsstatic isn't so evil... Bloch recommends its usage for making factories, for example. And of course, we don't want want Math.floor() to require an instance of Math! It can be useful, but used with care, of course.
-
jtoberon over 11 yearsI agree, but a purist once tried to convince me of just the opposite: that the
Math
methods should NOT be static! -
atamanroman over 11 yearsStatics are always potentially dangerous with testing or multithreading in mind. Of course there are many valid reasons to use statics.