Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-使用基类自动选择函数_Java_Function_Casting_Base Class - Fatal编程技术网

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

Java-使用基类自动选择函数,java,function,casting,base-class,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

简单地说,我有以下代码,有没有更好的方法

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

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

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

如果一致地命名类,则可以得到原始类名:

String classname = o.getClass().getClassName();
然后使用

Class.forName(classname + "MyVersion").newInstance();
(假设)为每个输入变量提供一个新的类实例,并使用公共基类中的方法设置原始对象引用。但是,您是否想这样做取决于您有多少变体,和/或该集合在未来改变的可能性有多大


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

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

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

static {
    Collections.addAll(validClasses, ShapedRecipes.class,
                                     ShapelessRecipes.class
                                     ShapedOreRecipe.class); //etc.
}
最后,不能直接执行强制转换,但可以使用反射来访问相应的构造函数:

Constructor<ShapelessRecursiveRecipe> constructor =
             ShapelessRecursiveRecipe.class.getConstructor(o.getClass());
constructor.newInstance(o);
构造函数=
shapelsRecursiverEcipe.class.getConstructor(o.getClass());
新实例(o);
我还没有测试过它,但它应该可以工作


它是否能使您的代码变得更好是有争议的-可能不是。

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

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

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

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

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);
}
静态ShapelessRecursiveRecipe转换器配方(T obj){
返回新的ShapelSecuriveRecipe(obj);
}
静态ShapelesSecuriveRecipe转换器配方(T obj){
返回新的ShapelSecuriveRecipe(obj);
}
静态ShapelesSecuriveRecipe转换器配方(T obj){
返回新的ShapelSecuriveRecipe(obj);
}
静态ShapelesSecuriveRecipe转换器配方(T obj){
返回新的ShapelSecuriveRecipe(obj);
}

你不能有一个基类,所有这些子类型的配方都可以从中派生出来吗?确实,但这不取决于我,因为这些类不是由我创建的,也不是由我维护的。所以你在
ShapelessRecursiveRecipe
?@assylias中每种类型都有一个构造函数,这是正确的。我将像在原始帖子中一样使用内省。在发布的解决方案中,我最喜欢这个。
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);
}