Using methods from a subclass of an object that is an instance of the superclass
Let's say there is a class that I use extensively and is returned by a method.
CommonClass obj = getCommonObject();
Now I want to extend this class to create some utility method to avoid repetition.
public CommonClassPlus extends CommonClass {
public String dontRepeatYourself() {
// the reason I'm creating a subclass
}
}
Of course, I would like to use my improved class for the above method, however, downcasting is not allowed.
CommonClassPlus obj = getCommonObject();
//Cannot cast to CommonClassPlus
How can I use the method dontRepeatYourself()
if I can only work with an object that is an instance of the superclass?
CommonClass
and getCommonObject()
are from an external library and I cannot change them.
source to share
If CommonClass
from an external library, you probably want to wrap it in an adapter pattern anyway, using the Composition over Inheritance principle .
This gives you complete control if you want to, say, change the library you are using, and allows you to add functionality such as dontRepeatYourself()
.
public class CommonClassAdapter implements MyAdapter {
private final CommonClass common;
private final String cachedResult;
// Note that I'm doing dependency injection here
public CommonClassAdapter(CommonClass common) {
this.common = common;
// Don't expose these because they shouldn't be called more than once
common.methodIOnlyCallOnce();
cachedResult = common.anotherMethodIOnlyCallOnce();
}
@Override
public void someMethod() {
common.someMethodWithDifferentName();
}
@Override
public String dontRepeatYourself() {
return cachedResult;
}
}
Note also that most modern IDEs have things like Eclipse Source -> Generate Delegate Methods
to speed up this process.
source to share
You cannot add behavior to an existing instance in Java (like JavaScript, for example).
The closest you can get in Java is the Decorator pattern:
CommonClassPlus obj = decorate(getCommonObject());
where decorate()
-
public CommonClassPlus decorate(CommonClass x) {
return new CommonClassPlus(x);
}
This approach creates a potentially huge amount of boilerplate because it must delegate the call of each method to the wrapped instance. If the method in CommonClass
is final and there is no interface that you can override, then this approach will completely fail.
In most cases, you should be able to get a simple static helper method:
public static String dontRepeatYourself(CommonClass x) {
...
}
source to share