在Java中根据某些条件确定实现类

在Java中根据某些条件确定实现类,java,class,Java,Class,我有一个接口“Parent”,和多个实现该接口的类(比如Abc.java、Def.java和Xyz.java)。现在我想做这样的事情: Parent factoryMethod(String condition){ Parent p = null; if(condition.equals("Abc")) p = new Abc(); else if(condition.equals("Def")) p = new Def(); el

我有一个接口“Parent”,和多个实现该接口的类(比如Abc.java、Def.java和Xyz.java)。现在我想做这样的事情:

Parent factoryMethod(String condition){
    Parent p = null;
    if(condition.equals("Abc"))
        p = new Abc();
    else if(condition.equals("Def"))
        p = new Def();
    else if(condition.equals("Xyz"))
        p = new Xyz();
    return p;
}
基本上,我将要实例化的类的名称作为参数传递给方法。最好的方法是什么?我应该为此使用反射吗?这不仅仅是3门课,可能还有更多。所以我不想写if/else


谢谢。

您可以根据试图为其创建对象的类的名称选择要使用的构造函数。比如:

Class-theClass=Class.forName(条件);
构造函数theClassConstructor=theClass.getConstructor();

Object Object=theClassConstructor.newInstance(新对象[]{args})

如果您知道完整的类名,您可以像这样使用反射API:

try {
    return Class.forName(condition).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
    // do something with exception
}

您可以使用枚举实现如下策略模式:

public enum ParentFactory {
    Abc(Abc.class),
    Def(Def.class),
    Xyz(Xyz.class);

    private Class<? extends Parent> childClass;

    private ParentFactory(Class<? extends Parent> childClass) {
        this.childClass = childClass;
    }

    public <T extends List> T getParentInstance() throws InstantiationException, IllegalAccessException {
        return (T) childClass.newInstance();
    }
}


public static void main(String[] args) throws InstantiationException, IllegalAccessException {
    ParentFactory parentFactory = ParentFactory.valueOf("Abc");
    Parent parent = parentFactory.getParentInstance();
}
公共枚举父工厂{
Abc(Abc.class),
定义(定义类别),
Xyz(Xyz.class);

private Class一种方法是将该方法定义为泛型方法,使用扩展的类型参数
Parent
,然后通过反射创建实例:

<T extends Parent> T factoryMethod(Class<T> clazz) throws Exception {
    return (T) clazz.newInstance();
}

但是,这假设父类的所有子类都没有参数构造函数(要么定义无参数构造函数,要么不定义任何构造函数,因此有一个可用的默认构造函数)。

是否保证所有实现类都有一个默认(无参数)构造函数(隐式或显式)?如果@PM77-1的评论是肯定的,我会根据这篇文章建议反思:你已经按照我建议的方式做了。如果你要这样做,最好是做Abc.class.getSimpleName().equals(condition)。如果我没有完整的类名,我该怎么办?
Abc abc = obj.factoryMethod(Abc.class);
Def def = obj.factoryMethod(Def.class);

// The below won't compile if SomeOtherClass does not implement Parent
SomeOtherClass instance = obj.factoryMethod(SomeOtherClass.class);