简体   繁体   中英

Java: Return an object that extends an abstract class which takes arguments

I've got an interface

public interface I
{
public AnAbstractClass k();  //Abstract Class constructor takes two arguments
}

For an implementation of this interface's method I want to return a generic object which extends that AbstractClass and also give it its two argument constructor

To clarify what I want to achieve. In a class which implements I:

public AnAbstractClass k()
{
   //return a new implementing AbstractClass object AbstractClassObject(arg1,arg2)
}

Constructors are not inherited, so subclasses of AnAbstractClass won't necessarily have a two-argument constructor. If a subclass does have a two-argument constructor, there is nothing stopping you from creating an instance of that subclass using the two-argument constructor and returning it:

public abstract class AnAbstractClass
{
    public AnAbstractClass(String foo, String bar) {
        System.out.format("created with (%s, %s)\n", foo, bar);
    }
}

public class BaseClass extends AnAbstractClass
{
    public BaseClass(String foo, String bar) {
        super(foo, bar);
    }
}

public interface I
{
    public AnAbstractClass k();
}

public class Implementation implements I
{
    @Override public AnAbstractClass k() {
        return new BaseClass("hello", "world");
    }
}

public class Demo
{
    public static void main(String[] args) {
        I i = new Implementation();
        AnAbstractClass a = i.k();
    }
}

There are sophisticated solutions for this problem (roughly: Everything that is related to dependency injection). However, in this case, there are not so many options: Someone HAS to provide these arguments, and they obviously can not be passed to the interface method. So you'll probably need something like

class Creator implements I
{
    private Object arg0;
    private Object arg1;
    void setArgs(Object arg0, Object arg1)
    {
        this.arg0 = arg0;
        this.arg1 = arg1;
    }

    @Override
    public AnAbstractClass k()
    {
        return new ConcreteClassExtendingAnAbstractClass(arg0, arg1);
    }

}

The drawback is that this interface might become more or less useless: If it was designed to be a factory, you can no longer use it in its abstract form...

I i = obtainFromSomewhere();
AnAbstractClass a = i.k();

but you always have to know the particular type

Creator i = obtainFromSomewhere();
i.setArgs(..., ...);
AnAbstractClass a = i.k();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM