Jaquarh
Jaquarh

Reputation: 6693

How to return an inherited object when stored using parent classname in Java

I am trying to create a Helper. My application can have many libraries, once instanced, I want to create a factory to be able to share the instance across classes, ie:

public ArrayList<Helper> helper = new ArrayList<>(asList(
    new Helper(SomeLib.class, new SomeLib()),
    new Helper(SomeOtherLib.class, new SomeOtherLib())
));

My Library class is standard as of the moment to test this working.

class Library {
    public Library() { System.out.println("Instance is working"); }
}

An example Library I am trying to get to work looks like this:

public class ExampleLib extends Library {
    public void test() { System.out.println("Test OK"); }
}

My current Helper class looks like this, however, I cannot cast the Library back to the original inherited class, I have tried multiple things:

import dreambot.libs.Library;

public class Helper {
    private Library lib;
    private Class<? extends Library> name;
    
    public Helper(Class<? extends Library> name, Library lib) {
        this.name = name;
        this.lib = lib;
    }
    
    public Class<? extends Library> getName() { return name; }
    public <Library> Library getLib() {
        // All the things I've tried to do
        return (this.name) lib;
        return name.cast(lib);
        return lib.getClass().cast(lib);
    }
}

In turn, what I want is:

public ArrayList<Helper> helper = new ArrayList<>(asList(
    new Helper(ExampleLib.class, new ExampleLib()),
));

public void test() {
    Arrays.stream(helper.toArray()).filter(c -> c.getName(ExampleLib.class)).getFirst().ifPresent(h -> {
        h.getLib().test(); // Should output "Test OK"
    });

The errors I am receiving in my IDE in the Helper::getLib method are:

Not a statement for return (this.name) lib;

Incompatible Types Required: Library, Found: dreambot.libs.Library for return lib.getClass().cast(lib); and return name.cast(lib);

Any help would be appreciated.

Upvotes: 0

Views: 40

Answers (1)

Konrad Adamek
Konrad Adamek

Reputation: 176

Try:

import dreambot.libs.Library;

public class Helper<T extends Library> {
    private T lib;
    private Class<T> name;

    public Helper(Class<T> name, Library lib) {
        this.name = name;
        this.lib = lib;
    }

    public Class<T> getName() { return name; }
    public T getLib() {
        return lib;
    }
}

or even simipler:

import dreambot.libs.Library;

public class Helper<T extends Library> {
    private T lib;

    public Helper(Library lib) {
        this.lib = lib;
    }

    public Class<T> getName() { return lib.getClass(); }
    public T getLib() {
        return lib;
    }
}

and don't forget about diamond operator during calling constructor:

public ArrayList<Helper> helper = new ArrayList<>(asList(
    new Helper<>(SomeLib.class, new SomeLib()),
    new Helper<>(SomeOtherLib.class, new SomeOtherLib())
));

which may be simplified to:

public ArrayList<Helper> helper = new ArrayList<>(asList(
    new Helper<>(new SomeLib()),
    new Helper<>(new SomeOtherLib())
));

Upvotes: 1

Related Questions