Extending a class that is instantiated by another class

I'm working with a Java API used for "macros" that automate a piece of software. The API has, among other things, the classes Simulation (a global state of sorts) and FunctionManager. There's nothing I can do to modify these classes.

I'd like to make a BetterFunctionManager class that extends FunctionManager because the latter lacks some useful features. But I don't know how to do this, because FunctionManager can't be instantiated directly. It must be gotten from Simulation, like this:

Simulation simulation = getCurrentSimulation();
FunctionManager functionManager = simulation.getFunctionManager();

Note that Simulation can't be instantiated directly either; it must be gotten via getCurrentSimulation() (the current simulation is determined at runtime by the macro interpreter).

I can't downcast; the following throws a ClassCastException:

BetterFunctionManager betterFunctionManager = simulation.getFunctionManager();

How can I construct BetterFieldFunctionManager?

Upvotes: 8

Views: 134

Answers (3)

Francisco Meza
Francisco Meza

Reputation: 883

What you have found is known as The Expression Problem and I'm afraid your most reasonable option to attack it with pure Java is StinePike's proposal of using composition and delegation

If you are in position to choose the tool for the task then I'd recommend you to take a look at Clojure Protocols. They offer a really nice solution to the expression problem (see very good explanation here Solving the Expression Problem with Clojure) and if I'm not mistaken if you end up coding your solution in clojure you can compile it into a java .class and use it in your java app

Upvotes: 2

stinepike
stinepike

Reputation: 54742

Disclaimer: I am still very naive about designing. Just a suggestion. use delegation design pattern

public class BetterFunctionManager{
    private FunctionManager fm;
    public  BetterFunctionManager(FunctionManager fm){
        this.fm = fm;
    }

    existingMethods(){
        fm.existingMethods();
    }

    newMethods(){
        // new implementation
    }
}

Disadvantages:

need to wrap all methods of FunctionManager

Advantage:

there is no need to change in any other place . just change like

BetterFunctionManager betterFunctionManager = 
                 new BetterFunctionManager (simulation.getFunctionManager());

Upvotes: 4

Juned Ahsan
Juned Ahsan

Reputation: 68715

As your options are limited due to the class structures, how about creating a FunctionManagerUtility class instead of BetterFunctionManager. In FunctionManagerUtility class you can add methods to add your useful features by taking FunctionManager object as an input.

Upvotes: 1

Related Questions