获得Foo.java的一个实现

时间:2012-10-04 13:33:14

标签: java interface enums

我有Foo.java,这是界面。

许多实现它的类。 Bar1.java , Bar2.java等。

我在前端有一个方法,就像这样:getBar(String bar)

我可以这样做:

if(bar.equals("Bar1")) {
    return new Bar1();
}

但我可以以某种方式做到这一点,每次新的实现Foo.java,然后我不必使用新的ELSE语句更新我的方法。

我认为每当我创建它时,每个实现都有唯一的ID或其他内容,我将其添加到BarX.java

有任何建议或想法吗?我想也许我可以使用enum或smthing或任何其他解决方案。

6 个答案:

答案 0 :(得分:2)

仅供参考:你当然意识到你不应该这样写:

if(bar == "Bar1") {
    return new Bar1();
}

你应该这样做:

if("Bar1".equals(bar)) {
    return new Bar1();
}

看起来你需要一个工厂(也就是虚拟构造函数)。如果您的所有Foo实现者都有默认构造函数,您可以这样做:

public class FooFactory {

    public static Foo create(Class<Foo> clazz) {
        return clazz.newInstance();
    }

    public static Foo create(String className) {
        return create(Class.forName(className));
    }
}

有待处理的例外情况;我没有时间为你拼出它们。你应该看到这个想法。你需要做的就是写一个新的类,你的工厂可以处理它。

如果有其他构造函数,只需使用参数和其他调用来详细说明主题。这应该可以帮到你。

答案 1 :(得分:2)

听起来像是依赖注入反射的工作。

你可以这样做:

Class myClass = Class.forName("my.namespace.MyClass");

那将是反思。不是很好,但做的工作。

答案 2 :(得分:1)

您可以按类名创建对象:

Class<?> clazz = Class.forName(className);
Object object = ctor.newInstance();

或者如果你需要调用特定的构造函数(例如String个参数strArgument):

Constructor<?> c = clazz.getConstructor(String.class);
Object object = c.newInstance(new Object[] { strArgument });

答案 3 :(得分:0)

这是一个典型的工厂模式问题。

解决方案是每当你需要维护静态地图时,无论何时你有新的“条形”类型,你都需要先在地图中注册它,所以无论何时你想要一个这种类型的对象,你都可以从地图。

考虑以下类

interface IVehicle {
    public void drive();
    public void stop();
}

class Car implements IVehicle {

    public void drive(){
        //logic goes here
    }

    public void stop(){
        //logic goes here
    }
}

class VehicleFactory{

    public IVehicle createVehicle(String VehicleType){
        IVehicle vehicle = null;

        if("Car".equalsIgnoreCase(VehicleType) ){
            vehicle = new Car();
        }
        if("Bus".equalsIgnoreCase(VehicleType) ){
            //vehicle = new Bus();
        }
        if("Train".equalsIgnoreCase(VehicleType) ){
            //vehicle = new Train();
        }
        return vehicle;
    }
}

所以每当你有一种新型车辆时,你必须通过添加新型车辆的代码来改变方法。

解决方法是改进VehicleFactory类,如下所示,所有车辆类型都应在地图中注册,如下所示。

class Car implements IVehicle {

    static{
        VehicleFactoryFlexible.registerVehicle("Car", new Car());
    }
    public void drive(){
        //logic goes here
    }

    public void stop(){
        //logic goes here
    }

    public IVehicle createVehicle(){
        return (IVehicle) new Car();
    }
}

public class VehicleFactoryFlexible {

    static Map vehicleRegistry = new HashMap();

    public static void registerVehicle(String vehicleType, IVehicle veh){
        vehicleRegistry.put(vehicleType, veh);
    }

    public IVehicle createVehicle(String vehicleType){
        IVehicle vehicle = (IVehicle)vehicleRegistry.get(vehicleType);
        return vehicle.createVehicle();
    }
}

答案 4 :(得分:0)

- Reflection是要走的路......

- 但你仍然可以使用像这样的方法

public static Foo createObj(Class<Foo> clazz) {
    return clazz.newInstance();
}

- 是的,它应该是equals()不是 ==

if(bar.equals("Bar1")) {
    return new Bar1();
}

答案 5 :(得分:0)

使用反射,您可以扫描整个包中的所有BarX类,并使用此列表实例化,如果您的输入存在于列表中。或者您可以使用Class.forName解决方案直接捕获错误。 编辑:检查出http://code.google.com/p/reflections/