基于Java中的某些条件确定实现类

时间:2015-02-13 21:49:18

标签: 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();
    else if(condition.equals("Xyz"))
        p = new Xyz();
    return p;
}

基本上我将要实例化的类的名称作为方法的参数传递。这样做的最佳方式是什么?我应该使用反射吗?它不仅仅是3个类,还可能有更多。所以我不想写if / else。

感谢。

4 个答案:

答案 0 :(得分:3)

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

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

然后您可以按如下方式使用该方法:

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); 

然而,这假设Parent的所有子类都没有参数构造函数(他们定义了无参数构造函数,或者他们没有定义任何构造函数,因此可以使用默认构造函数)。

答案 1 :(得分:1)

您可以使用枚举来实现这样的策略模式:

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();
}

答案 2 :(得分:0)

您可以根据要为其创建对象的类的名称选择要使用的构造函数。类似的东西:

Class<?> theClass = Class.forName(condition); Constructor<?> theClassConstructor = theClass.getConstructor(); Object object = theClassConstructor.newInstance(new Object[] { args });

答案 3 :(得分:0)

如果你知道完整的类名,你可以像这样使用Reflection API:

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