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.

+3


source to share


2 answers


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.

+2


source


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) {
   ...
}

      

+3


source







All Articles