【问题标题】:Java - Automatic function selection using base classJava - 使用基类自动选择函数
【发布时间】:2013-08-05 20:37:50
【问题描述】:

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

另外,我不能修改任何配方类。

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

【问题讨论】:

  • 你不能有一个基类来派生所有这些子类型的食谱吗?
  • 确实如此,但这不取决于我,因为这些类不是我创建的,也不是我维护的。
  • 所以ShapelessRecursiveRecipe 中的每种类型都有一个构造函数?
  • @assylias 没错。

标签: java function casting base-class


【解决方案1】:

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

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】:

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

如果你一致地命名你的类,那么你可以得到原来的类名:

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

然后使用

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

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

不会返回 null,但是,如果您没有找到匹配项。我宁愿抛出一个明确的异常。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 2016-09-23
        • 2023-03-05
        • 2019-07-11
        • 1970-01-01
        • 2012-10-21
        • 1970-01-01
        • 2011-01-06
        • 2016-09-23
        • 2013-07-24
        相关资源
        最近更新 更多