Java - 使用基类自动选择函数

时间:2013-08-05 07:49:03

标签: java function casting base-class

简单地说,我有以下代码,有没有更好的方法来做到这一点?

另外,我无法修改任何食谱类。

public static ShapelessRecursiveRecipe convertRecipe(Object o)
{
    //might be a better way to do this
    if(o instanceof ShapedRecipes)
        return new ShapelessRecursiveRecipe((ShapedRecipes)o);
    else if(o instanceof ShapelessRecipes)
        return new ShapelessRecursiveRecipe((ShapelessRecipes)o);
    else if(o instanceof ShapedOreRecipe)
        return new ShapelessRecursiveRecipe((ShapedOreRecipe)o);
    else if(o instanceof ShapelessOreRecipe)
        return new ShapelessRecursiveRecipe((ShapelessOreRecipe)o);
    else
        return null;
}

4 个答案:

答案 0 :(得分:0)

如果你不能修改基类,那么我认为上面是一个合适的实用解决方案。

如果您一致地命名您的类,那么您可以获得原始的类名:

String classname = o.getClass().getClassName();

然后使用

实例化一个新类
Class.forName(classname + "MyVersion").newInstance();

(比如说)为每个输入变体创建一个类型的新类实例,并使用公共基类中的方法设置原始对象引用。但是,您是否要这样做取决于您拥有的变体数量,和/或该集合在未来发生变化的可能性。

不会返回null,但是,如果找不到匹配项。我宁愿抛出一个明确的例外。

答案 1 :(得分:0)

我能想到的唯一选择是相当复杂并涉及反思。您可以将有效类放在集合中:

private static final Set<Class<?>> validClasses = new HashSet<Class<?>> ();

static {
    Collections.addAll(validClasses, ShapedRecipes.class,
                                     ShapelessRecipes.class
                                     ShapedOreRecipe.class); //etc.
}

然后你可以用以下内容替换instanceof:

if (o != null && validClasses.contains(o.getClass())) {

最后,无法直接完成转换,但您可以使用反射来访问相应的构造函数:

Constructor<ShapelessRecursiveRecipe> constructor =
             ShapelessRecursiveRecipe.class.getConstructor(o.getClass());
constructor.newInstance(o);

我没有测试过,但它应该有用。

是否让你的代码更好是有争议的 - 可能不是。

答案 2 :(得分:0)

如果您的所有食谱类派生自基类Recipe,那么您可以将Recipe参考作为参数:

public static ShapelessRecursiveRecipe convertRecipe(Recipe o)
{
return new ShapelessRecursiveRecipe(o);
}

您可以在构造函数中检查对象的类型,或者如果只调用它们的方法,则polymorphysm会自动调用每个子类的方法。

答案 3 :(得分:0)

另一种方式,不确定这是否更好地使用如下的泛型......

static <T extends ShapedRecipes>  ShapelessRecursiveRecipe convertRecipe(T obj) {
  return new ShapelessRecursiveRecipe(obj);
}

static <T extends ShapelessRecipes> ShapelessRecursiveRecipe convertRecipe(T obj) {
  return new ShapelessRecursiveRecipe(obj);
}

static <T extends ShapedOreRecipe> ShapelessRecursiveRecipe convertRecipe(T obj) {
  return new ShapelessRecursiveRecipe(obj);
}

static <T extends ShapelessOreRecipe> ShapelessRecursiveRecipe convertRecipe(T obj) {
  return new ShapelessRecursiveRecipe(obj);
}