Reputation: 33389
I have an abstract class type that I'm inheriting from to create new classes. As an equivalent example, consider:
public abstract class BaseClass {
public BaseClass(String input)
{
...
}
public abstract void doSomething();
public String getResult()
{
...
}
}
Now I can override BaseClass and implement "doSomething" to perform different actions (for example, reverse or capitalize, if I were really working with strings, though I'm not really, it's just an example).
The most common usage is:
BaseClass bc = new ExtendsBaseClass(input);
bc.doSomething();
String result = bc.getResult()
So I want to make a static wrapper method for this.
I'd like to implement:
public static String doSomethingForResult(String input)
{
BaseClass bc = /*new current type*/;
bc.doSomething();
return bc.getResult();
}
But I have no idea what to replace that comment with, or how to make it work; I don't want to force every implementing class to re-implement this (if that's even conceptually possible; since abstract static
is not allowed.
Upvotes: 0
Views: 1292
Reputation: 7952
So I want to make a static wrapper method for this.
I think I see why you might want to do this. You want a simple method to perform a common set of operations without having keep copying the boilerplate code again and again. But as you are painfully aware by now, static methods have no place in an inheritance hierarchy. I would recommend you get inspiration from the various Apache Commons projects and their XxxUtils classes which are composed solely of static methods and exist completely outside of the hierarchy of the classes they act on.
Consider the class FileUtils in Commons IO. It's just static methods but they are so helpful. Consider two methods:
static byte[] readFileToByteArray(File file) // Reads the contents of a file into a byte array.
static String readFileToString(File file) // Reads the contents of a file into a String
One methods deals with files and byte arrays, the other deals with files and strings? How do you know which does what - because it uses a descriptive name which spells it out. The are no inheritance, implementation, polymorphism issues because FileUtils exists completely outside the inheritance hierarchy of Files, Strings, byte arrays etc.
Let's get back to your hypothetical method. I would put this method in a separate class named MyUtils - or BitmapUtils and create a method for every combination of concrete classes that was meaningful.
public static String doSomethingWithExtendsBaseClass(String input)
{
BaseClass bc = new ExtendsBaseClass();
bc.doSomething();
return bc.getResult();
}
public static String doSomethingWithOtherClass(String input)
{
BaseClass bc = new OtherClass();
bc.doSomething();
return bc.getResult();
}
But I have no idea what to replace that comment with, or how to make it work
Simple - you just instantiate the concrete class directly in the method with the corresponding name.
Upvotes: 0
Reputation: 22171
Why do you bother with static things in this case?
Just benefit from polymorphism and merge doSomething()
and getResult()
.
You would end up with:
public abstract class BaseClass {
public BaseClass(String input)
{
...
}
public abstract String doSomething();
}
and your client would look like:
BaseClass bc = new ExtendsBaseClass(input);
String result = bc.doSomething();
In generally, defining a separated getResult()
method would make sense in specific cases like in implementing Builder Pattern. Indeed, several distinct methods participate to the object construction and end up with a call to a kind of getResult()
method.
---------------------After your comment just below------------------------
If, as you said, the common case was to use doSomething()
follows by getResult()
and depending on a specific subclass, you could use Template Method pattern:
public abstract class BaseClass {
public BaseClass(String input)
{
// assigments
}
public String process(){ //process is a template method
doSomething();
return getResult();
}
protected abstract void doSomething();
protected abstract String getResult();
}
public class ExtendedClass extends BaseClass {
protected void doSomething(){
//...
}
protected String getResult(){
//....
}
}
Your client would only call process()
method:
BaseClass bc = new ExtendsBaseClass(input);
String result = bc.process();
But please :), avoid static things when possible, they aren't lead to a good OO programming.
Upvotes: 2
Reputation: 34367
I think you can define a static method in BaseClass
and pass the other class as argument to it using BaseClass
as argument class e.g.
public static String doSomethingForResult(String input ,BaseClass bc){
bc.doSomething();
return bc.getResult();
}
Then in your ExtendedBaseClass
you may write as:
ExtendedBaseClass extendedBaseObject= new ExtendedBaseClass();
String result = BaseClass.doSomethingForResult("input", extendedBaseObject);
System.out.println(result);
Upvotes: -1
Reputation: 691685
Static methods are not polymorphic, and thus can't be inherited and overridden. What you want to do is impossible.
Upvotes: 2